Sql 选择是否阻止删除返回的行?
假设我有:Sql 选择是否阻止删除返回的行?,sql,postgresql,database-locking,read-committed,Sql,Postgresql,Database Locking,Read Committed,假设我有: T1:从x中选择id,其中时间戳
从x中选择id,其中时间戳
(返回id=[1,2,3]
)从x中删除,其中id=1
选择时间戳,从x中选择值,其中id=1
读提交
隔离
步骤3是否存在返回空结果的风险,或者步骤1是否获取某种锁/快照以防止步骤2更改结果?(我假设,REPEATABLE-READ
会做我想做的事情,但这个问题是关于READ-COMMITTED
)
我正在使用postgresql,但我对DB独立的答案感兴趣。例如,如果一些数据库阻止删除,而其他数据库则不阻止删除,我想知道这一点。谢谢。PostgreSQL案例: 在PostgreSQL中,读取一行不会获得阻止该行同时删除的锁:
- 如果T2在步骤3之前提交,T1将看到其结果并返回一个空结果集
- 如果在T2提交之前运行步骤3,那么T2的结果还不可见,查询将返回匹配的行
- 一些数据库系统,如DB2或Microsoft SQL Server,在读取行时会锁定行,以防止并发更新
在这样的数据库系统上,
将被阻止,并且该行在步骤3中可见DELETE
- 大多数数据库系统使用某种类型的多版本控制,即在修改行的事务进行时,它们保留行的旧版本
在这样的数据库系统上,
不会被阻止,步骤3的结果将取决于T2是否已经提交DELETE
如果您正在寻找一种解决方案,使行为在所有数据库系统上都具有确定性,那么您可以使用更高的隔离级别,也可以通过在步骤1的
SELECT
语句中指定for UPDATE
来使用悲观锁定。然后步骤2将始终阻塞。PostgreSQL案例:
在PostgreSQL中,读取一行不会获得阻止该行同时删除的锁:
- 如果T2在步骤3之前提交,T1将看到其结果并返回一个空结果集
- 如果在T2提交之前运行步骤3,那么T2的结果还不可见,查询将返回匹配的行
- 一些数据库系统,如DB2或Microsoft SQL Server,在读取行时会锁定行,以防止并发更新
在这样的数据库系统上,
将被阻止,并且该行在步骤3中可见DELETE
- 大多数数据库系统使用某种类型的多版本控制,即在修改行的事务进行时,它们保留行的旧版本
在这样的数据库系统上,
不会被阻止,步骤3的结果将取决于T2是否已经提交DELETE
如果您正在寻找一种解决方案,使行为在所有数据库系统上都具有确定性,那么您可以使用更高的隔离级别,也可以通过在步骤1的
SELECT
语句中指定for UPDATE
来使用悲观锁定。然后步骤2将始终阻塞。它确实取决于DBMS及其设置。例如,在SQL Server中,可以打开和关闭快照隔离。在没有具体提示的情况下,步骤1中的simpleSELECT
不应阻止T2删除该行。(我假设步骤2在步骤1完成后运行,事务T1尚未结束这一事实并不重要)@VladimirBaranov谢谢。而REPEATABLE-READ
将阻止T2删除该行(或至少从快照中隐藏该行),对吗?对不起,我对该隔离级别没有太多经验<代码>可序列化应该足够了。不同的DBMS可能实现的隔离级别略有不同,因此您最好检查您的DBMS的文档,以便SQL ServerREPEATABLE READ
looks life足够了。“指定语句不能读取其他事务已修改但尚未提交的数据,并且在当前事务完成之前,其他事务不能修改当前事务已读取的数据。共享锁放置在事务中每个语句读取的所有数据上,并保留到transaction已完成。这将防止其他事务修改当前事务已读取的任何行。“有关Postgres,请参阅其docsIt,这取决于DBMS及其设置。例如,在SQL Server中,可以打开和关闭快照隔离。在没有具体提示的情况下,步骤1中的simpleSELECT
不应阻止T2删除该行。(我假设步骤2在步骤1完成后运行,事务T1尚未结束这一事实并不重要)@VladimirBaranov谢谢。而REPEATABLE-READ
将阻止T2删除该行(或至少从快照中隐藏该行),对吗?对不起,我对该隔离级别没有太多经验<代码>可序列化应该足够了。不同的DBMS可能实现的隔离级别略有不同,因此您最好检查您的DBMS的文档,以便SQL ServerREPEATABLE READ
looks life足够了。“指定语句无法读取已修改但尚未由其他事务提交的数据,并且没有ot