我有一个分布式应用程序,它使用数据库来同步客户端。客户端将尝试更新记录,但只有在过去 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
之前解决(因为它必须首先使用它来查找行),所以似乎存在竞争条件:
- 客户端“红色”计算
sysdate
- 客户“Green”计算
sysdate
- 1小时通行证
- 客户端“红色”更新
TimeOfLastUpdate
为旧sysdate
- 客户端“绿色”更新
TimeOfLastUpdate
旧sysdate
(因此更新两次)
我将其确定为比赛条件是否正确?如果没有,我错过了什么?
如果是这样,是否有有效、更可靠的解决方案来解决这个问题?