0

说我有:

  1. T1:(SELECT id FROM x WHERE timestamp < y返回id = [1, 2, 3]
  2. T2:DELETE FROM x WHERE id = 1
  3. T1:SELECT timestamp, value FROM x WHERE id = 1

READ-COMMITTED隔离。

第 3 步是否存在返回空结果的风险,或者第 1 步是否获得某种锁定/快照以防止第 2 步更改结果?(我假设REPEATABLE-READ会做我想做的事,但这个问题是关于READ-COMMITTED)。

我正在使用 postgresql,但我对独立于 DB 的答案感兴趣。例如,如果某些数据库阻止删除而其他数据库不阻止,我想知道这一点。谢谢你。

4

1 回答 1

2

PostgreSQL 案例:

在 PostgreSQL 中,读取一行不会获得阻止该行被同时删除的锁:

  • 如果 T2 在步骤 3 之前提交,T1 将看到其结果并返回一个空结果集。

  • 如果步骤 3 在 T2 提交之前运行,则 T2 的结果尚不可见,查询将返回匹配的行。

一般情况:

数据库系统有不同的方式来提供事务隔离,并且行为会根据使用的方法而有所不同。

  • 一些数据库系统,如 DB2 或 Microsoft SQL Server,会在读取行时锁定行以防止并发更新。

    在这样的数据库系统上,DELETE将阻塞,并且该行在步骤 3 中可见。

  • 大多数数据库系统使用某种多版本控制,即在修改行的事务正在进行时,它们保留旧版本的行。

    在这样的数据库系统上,DELETE不会阻塞,步骤 3 的结果将取决于 T2 是否已经提交。

一个解法:

如果您正在寻找使所有数据库系统上的行为具有确定性的解决方案,您可以使用更高的隔离级别,也可以通过在步骤 1中的语句中指定来使用悲观锁定。然后步骤 2 将始终阻塞。FOR UPDATESELECT

于 2018-02-16T05:35:33.933 回答