Sql 选择是否阻止删除返回的行?

Sql 选择是否阻止删除返回的行?,sql,postgresql,database-locking,read-committed,Sql,Postgresql,Database Locking,Read Committed,假设我有: T1:从x中选择id,其中时间戳

假设我有:

  • T1:
    从x中选择id,其中时间戳
    (返回
    id=[1,2,3]
  • T2:
    从x中删除,其中id=1
  • T1:
    选择时间戳,从x中选择值,其中id=1
  • 通过
    读提交
    隔离

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


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

    PostgreSQL案例:

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

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

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

    一般情况:

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

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

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

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

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

    解决方案:


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

    PostgreSQL案例:

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

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

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

    一般情况:

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

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

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

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

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

    解决方案:


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

    它确实取决于DBMS及其设置。例如,在SQL Server中,可以打开和关闭快照隔离。在没有具体提示的情况下,步骤1中的simple
    SELECT
    不应阻止T2删除该行。(我假设步骤2在步骤1完成后运行,事务T1尚未结束这一事实并不重要)@VladimirBaranov谢谢。而
    REPEATABLE-READ
    将阻止T2删除该行(或至少从快照中隐藏该行),对吗?对不起,我对该隔离级别没有太多经验<代码>可序列化
    应该足够了。不同的DBMS可能实现的隔离级别略有不同,因此您最好检查您的DBMS的文档,以便SQL Server
    REPEATABLE READ
    looks life足够了。“指定语句不能读取其他事务已修改但尚未提交的数据,并且在当前事务完成之前,其他事务不能修改当前事务已读取的数据。共享锁放置在事务中每个语句读取的所有数据上,并保留到transaction已完成。这将防止其他事务修改当前事务已读取的任何行。“有关Postgres,请参阅其docsIt,这取决于DBMS及其设置。例如,在SQL Server中,可以打开和关闭快照隔离。在没有具体提示的情况下,步骤1中的simple
    SELECT
    不应阻止T2删除该行。(我假设步骤2在步骤1完成后运行,事务T1尚未结束这一事实并不重要)@VladimirBaranov谢谢。而
    REPEATABLE-READ
    将阻止T2删除该行(或至少从快照中隐藏该行),对吗?对不起,我对该隔离级别没有太多经验<代码>可序列化应该足够了。不同的DBMS可能实现的隔离级别略有不同,因此您最好检查您的DBMS的文档,以便SQL Server
    REPEATABLE READ
    looks life足够了。“指定语句无法读取已修改但尚未由其他事务提交的数据,并且没有ot