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