让我们考虑两个并发的SQL事务:
X = 0
T1: | T2:
begin | begin
set serializable level | set serializable level
|
WRITE(X,1)
| READ(X) : 0
COMMIT |
| COMMIT
我已经用PosgreSQL对其进行了测试。
为什么T2
正确提交?这两个事务都有可序列化的级别。因此,在我看来, 之后T2
开始了,行X
被修改了。因此,T2:COMMIT
应该失败。为什么不呢?
答案 0 :(得分:1)
实际上,一个SELECT查询可以看到数据库的快照。 查询开始运行的瞬间。 Source
SELECT查询将仅对该快照进行操作。但是其他类型的查询的行为也与您期望的一样。
UPDATE,DELETE,SELECT FOR UPDATE和SELECT FOR SHARE。 。 。将等待第一个更新事务提交或回滚(如果仍在进行中)。 Source (ibid)
例如,可以通过运行两个psql会话来验证此行为。在一个会话中运行UPDATE语句,在另一个会话中运行SELECT ... FOR UPDATE。