说我有:
SELECT id FROM x WHERE timestamp < y
(返回id = [1, 2, 3]
)DELETE FROM x WHERE id = 1
SELECT timestamp, value FROM x WHERE id = 1
READ-COMMITTED
隔离。
步骤3是否存在返回空结果的风险,或者步骤1是否获得某种锁定/快照以防止步骤2更改结果? (我假设REPEATABLE-READ
会做我想要的,但这个问题是关于READ-COMMITTED
)。
我正在使用postgresql,但我对独立于数据库的答案感兴趣。例如,如果某些数据库阻止删除而其他数据库没有阻止删除,我想知道这一点。谢谢。
答案 0 :(得分:1)
PostgreSQL案例:
在PostgreSQL中,读取一行并不会获得阻止同时删除行的锁:
如果T2在步骤3之前提交,T1将看到其结果并返回空结果集。
如果第3步在T2提交之前运行,则T2的结果尚不可见,查询将返回匹配的行。
一般情况:
数据库系统有不同的方式来提供事务隔离,行为将根据使用的方法而有所不同。
某些数据库系统(如DB2或Microsoft SQL Server)会在读取行时锁定行以防止并发更新。
在此类数据库系统上,myPojo.getMapAttrValue().put(key,value)
将阻止,并且该行在步骤3中可见。
大多数数据库系统使用某种多版本化,即在修改行的事务正在进行时,它们会保留旧版本的行。
在此类数据库系统上,DELETE
未被阻止,步骤3的结果将取决于T2是否已提交。
解决方案:
如果您正在寻找使所有数据库系统的行为具有确定性的解决方案,您可以使用更高的隔离级别,也可以通过指定DELETE
来使用悲观锁定步骤1中的FOR UPDATE
语句。然后步骤2将始终阻止。