我基本上需要一个 UPSERT 功能,每天创建一次行,并从那时起更新到第二天。从业务角度来看,每天必须有 1 行或 0 行。
我的问题显然是并发性和两个会话同时创建这一行。
据我了解,
SELECT ... WHERE day = today FOR UPDATE
不会阻止第二个会话立即获得(0行)结果(如果该行不存在)。
我的解决方案:
我创建一个表只是为了锁定某个“资源”,例如
SELECT * FROM my_semaphore WHERE resource = 'daily' FOR UPDATE
,然后继续在其他表上执行我的实际业务逻辑(我现在不需要锁定)。具有 resource = 'daily'
的行明确存在,因此我知道所有其他会话,想要此资源需要等待,直到第一个会话提交其事务。
我向你们提出的问题:有没有更聪明的方法,我错过了什么吗?
提前感谢大家!
假设您有
day
列的主键,并且更新功能为您的日行添加了值,您可以使用 ON DUPLICATE KEY UPDATE
:
INSERT INTO yourtable (day, value)
VALUES(current_date(), YOURVALUE)
ON DUPLICATE KEY UPDATE value = value + YOURVALUE;