根据SQL Server中的快照隔离级别,在启用READ_COMMITTED_SNAPSHOT
之前,是否确实需要先启用ALLOW_SNAPSHOT_ISOLATION
?。
Azure SQL创建的实例似乎没有启用它,尽管它们的隔离级别设置为READ_COMMITTED_SNAPSHOT
。
我真的不明白ALLOW_SNAPSHOT_ISOLATION
是必需的,还是在启用READ_COMMITTED_SNAPSHOT
之前没有设置它的后果
我在虚拟机中托管的生产数据库中遇到了死锁。
事务(进程ID XX)与另一个进程在锁资源上死锁,已被选为死锁牺牲品。重新运行事务。
其中一个事务是SELECT
(持有S锁),而另一个事务则是INSERT
(持有IX锁定)。
在尝试将其复制到包含我们生产数据备份的SQL Azure数据库后,我一直无法复制,直到我意识到隔离级别(通过DBCC USEROPTIONS
获得)存在差异
Azure(SQLServer12.0.2000.8): 读取提交的快照
VM托管(SQLServer15.0.2080.9): 读取提交
在通过运行ALTER DATABASE MyDatabase SET READ_COMMITTED_SNAPSHOT OFF
匹配Azure DB中的隔离级别后,我能够重现该问题。
现在,我想将读取提交的快照设置为生产数据库中的隔离级别。上面提到的链接表明我需要运行这两个命令:
ALTER DATABASE MyDatabase
SET ALLOW_SNAPSHOT_ISOLATION ON
ALTER DATABASE MyDatabase
SET READ_COMMITTED_SNAPSHOT ON
然而,Azure DB中似乎不允许快照隔离(SELECT snapshot_isolation_state_desc FROM sys.databases WHERE NAME = 'MyDatabase'
返回OFF)
我也无法在Azure SQL实例的系统数据库中找到tempdb
。
之前是否真的需要启用ALLOW_SNAPSHOT_ISOLATION根据中的快照隔离级别启用READ_COMMITTED_SNAPSHOTSQL Server?。
Azure SQL创建的实例似乎没有启用它,尽管其隔离级别设置为READ_COMMITTED_SNAPSHOT。
无需启用ALLOW_SNAPSHOT_ISOLATION
即可启用READ_COMMITTED_SNAPSHOT
,反之亦然。只有当显式使用SNAPSHOT
隔离(SET TRANSACTION ISOLATION LEVEL SNAPSHOT
)时,才需要ALLOW_SNAPSHOT_ISOLATION
,而READ_COMMITTED_SNAPSHOT
将READ_COMMITTED
隔离级别(默认级别)的行为更改为使用行版本控制而不是锁定以实现语句级读取一致性。
尽管两者都使用行版本控制,但一个重要的区别是READ_COMMITTED_SNAPSHOT
返回语句开始时的数据快照,而SNAPSHOT
隔离级别返回事务开始时的一个数据快照,这是包含多个查询的事务的一个重要考虑因素。两者都将为单语句自动提交事务提供相同的行为。
否,启用READ_COMMITTED_SNAPSHOT
隔离级别时不需要ALLOW_SNAPSHOT_ISOLATION
。
当启用READ_COMMITTED_SNAPSHOT
隔离级别时,您需要设置READ_COMMITTED
隔离级别并使用下面的MSSQL命令打开READ_COMMITTED_SNAPSHOT
:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
ALTER DATABASE <database_name> SET READ_COMMITTED_SNAPSHOT ON
GO
此外,当启用SNAPSHOT
隔离级别时,您需要设置SNAPSHOT
隔离级别并使用下面的MSSQL命令打开ALLOW_SNAPSHOT_ISOLATION
:
SET TRANSACTION ISOLATION LEVEL SNAPSHOT
ALTER DATABASE <database_name> SET ALLOW_SNAPSHOT_ISOLATION ON
GO