我基本上需要一个 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;