SQL 服务器读取已提交的快照

SQL Server Read Committed Snapshot

我只是想知道有关已提交读隔离级别的快照行为的一些信息。假设我有一个名为 "A" 的 table。这是第一笔交易:

Select blabla 
From A

Insert Into A blabla

第二笔交易做同样的事情

Select blabla 
From A

Insert Into A blabla

并假设以下时间线发生:

Tran1: select
Tran1: insert (not yet committed)
Tran2: select (I don't know it is possible or not)
Tran2: insert

据我所知,在标准的读取已提交隔离级别中,tran2 select 查询将被阻止,因为 tran1 插入命令尚未提交或回滚。但是,虽然启用了 "is_read_committed_snapshot",但我预计在插入或更新命令期间不会获取任何锁。

那么 tran2 会怎样?

我希望 tran2 select 查询不会看到 tran1 插入的数据,因为它会是 "dirty read"。但它也不会被阻止。

因为tran1插入查询没有获取任何锁,这种情况不会是这两个事务执行的并发问题吗?

假设您是这样做的:

SELECT id FROM customers

BEGIN TRAN new_tran
UPDATE customers

设置 ID = '1' 其中 ID = '01'

如果您的查询是这样的:

SET TRANSACTION ISOLATION LEVEL SNAPSHOT
GO
BEGIN TRAN
SELECT *
FROM   customers
WHERE id = '01'

结果 - 即使我们将值更改为 01,我们仍然会在会话 2 (2, TWO) 中看到旧记录。

现在,让我们在会话 1 中提交事务

现在假设您在会话 2 中提交事务,现在您将获得新的更新值:

COMMIT
SELECT *
FROM   DemoTable
WHERE i = 2

您可以在 Pinal Dave 的博客上阅读更多相关信息:blog.sqlauthority.com/2015/07/03/sql-server-difference-between-read-committed-snapshot-and-snapshot-isolation-level/

I expect that any of lock won't acquired during insert or update command.

这是错误的。即使您已启用 RCSI,写入器仍会阻止写入器,并且仍会获得 X 锁。

RC 和 RCSI 之间的区别在于阅读行为。 在悲观 RC 上工作时,来自 Tran2 的 SELECT 将被 A 上持有的 X 锁阻塞,而在 RCSI Tran2 上工作时 SELECT 将不会被阻塞,它将与最后提交的一起提供A 的版本,即 A 的状态 before Tran1 修改了它。

接下来会发生什么取决于您的 table 组织和您 INSERT

一些例子。

1) table A 是一个堆,你在两个事务中都做单插入。

在这种情况下,您在 Tran2 中的 INSERT 在任何情况下都会成功,无论您是否尝试在两个事务中插入相同的值,因为在这种情况下,服务器获取的是 table 上的 IX(与 Tran1 持有的 IX 兼容),页面上的 IX(也与 IX 由 Tran1 持有,即使它是同一页),并且 X 在 RID 上(而 Tran1 在 另一个 RID 上有 X),所以有没有冲突。

2) table A 被聚类 table,您正试图在此 table 中插入 相同的新密钥

在这种情况下,您的 Tran2 的 INSERT 将被阻止,因为同一键上的两个 X 锁之间存在冲突,第一个由 Tran1 持有,第二个由 Tran2 请求并且是已屏蔽。

3) table A 被聚类 table,您正试图在此 table.[=31= 中插入 不同的键 ]

Insert2 将成功,因为 Tran2 请求的密钥 X 锁定将被授予,因为 Tran1 在 table、IX 和 [=11 上持有 IX =] 在 another 键上。