我想要 Postgresql 中的事务有某种行为,但我不知道这是否可能。我将这种行为描述为“乐观读锁”,但这似乎不是正确的术语。
这是我想要的行为:
- 我的交易开始了。其事务隔离级别是“可重复读”或“可串行化”。
- 在事务中我读取了 A 行。
- 在事务中我做了更多的读取和写入,但我从不更新 A 行。
- 我尝试提交交易。
现在,如果 A 行在我的事务生命周期内被其他事务更改,我需要事务失败。如果 A 行没有改变,我希望事务能够提交。
有没有办法在 Postgresql 中做到这一点?
我的替代方法是使用事务中的一些随机值更新 A 行,以强制写入冲突。然而,这将意味着很多不必要的冲突,因为如果不强制冲突,A 行将很少被更新,但经常被读取。
您可能正在谈论这样的情况:
现在事务 1 总结了这些事件:
在事务 1 提交之前,事务 2 插入较旧的行:
并且事务1提交时不会出现错误。
一个可能的解决方案是事务 2 在插入新行后读取汇总表。让我们看看它是如何工作的:
交易1:
交易2:
现在当事务 1 提交时:
由于事务 2 查看
summary
并没有看到摘要行,因此它在逻辑上运行在事务 1 之前。但是由于事务 1 没有看到其结果,因此它在逻辑上运行在事务 2 之前。这种矛盾导致了序列化错误。如果事务 2 找到
summary
一行,则它处于困境,它应该回滚并丢弃新值或尝试修复摘要。如果这不是一个选择,那么您将不得不使用大锁真正序列化操作,这不是很有吸引力。