我有一个使用数据库来同步客户端的分布式应用程序。客户将尝试更新记录,但只有在过去1小时内没有其他客户这样做时才会这样做。如何以时间戳原子更新一行?
这里是缩小的代码和困境:
说一个客户端尝试更新的字段“红”(检查没有其他人在过去一小时内更新它):
UPDATE mytesttable
SET Status = 'Red',
TimeOfLastUpdate = sysdate
WHERE TimeOfLastUpdate < sysdate-1/24
,并在同一时间,另一客户端尝试更新其为“绿色”(检查没有其他人在过去一小时内更新它):
UPDATE mytesttable
SET Status = 'Green',
TimeOfLastUpdate = sysdate
WHERE TimeOfLastUpdate < sysdate-1/24
我能否假设只有一个客户端才能成功更新该行?
这也是为什么我认为答案是“不”:
因为Oracle必须解决前sysdate
它获得的行级更新锁(因为它必须使用它来查找行第1名),它似乎有一个竞争条件:
- 客户端“红”计算
sysdate
- 客户“绿色”计算
sysdate
- 1小时传递
- 客户端 “红” 的更新
TimeOfLastUpdate
与旧sysdate
- 客户端的 “绿色” 与旧
sysdate
更新TimeOfLastUpdate
(由此更新两次)
我是正确识别此作为竞赛条件?如果不是,我错过了什么?
如果是这样,是否有一个有效的,更可靠的解决这个问题?
虽然不完全是你的问题,但我认为接受的答案也是我对你的建议。如果您绝对必须确保只有一个人更新它,请使用序列。 http://stackoverflow.com/questions/8498169/race-condition-between-select-and-update –