Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 读取\提交\快照和快照隔离中的共享锁_Sql Server_Sql Server 2008_Read Committed Snapshot_Snapshot Isolation - Fatal编程技术网

Sql server 读取\提交\快照和快照隔离中的共享锁

Sql server 读取\提交\快照和快照隔离中的共享锁,sql-server,sql-server-2008,read-committed-snapshot,snapshot-isolation,Sql Server,Sql Server 2008,Read Committed Snapshot,Snapshot Isolation,我在微软的网站上读过 Sql Server在读取数据时不会请求锁定,除非数据库正在恢复 这是否意味着使用读取提交快照/快照隔离的Sql Server根本不使用共享锁? 这怎么可能 例如,如果有2个事务。 第一个事务T1想要更新某些行。 第二个事务T2开始读取同一行(此事务将他复制到某个输出缓冲区、响应缓冲区或Sql Server中的任何调用)。 同时,事务T1开始更新该行(它首先创建了版本化的行) 事务T2是否有可能读取未限制的数据? 请记住,事务T2在T1进行更新之前开始复制该行,因此该行上

我在微软的网站上读过

Sql Server在读取数据时不会请求锁定,除非数据库正在恢复

这是否意味着使用读取提交快照/快照隔离的Sql Server根本不使用共享锁? 这怎么可能

例如,如果有2个事务。 第一个事务T1想要更新某些行。 第二个事务T2开始读取同一行(此事务将他复制到某个输出缓冲区、响应缓冲区或Sql Server中的任何调用)。 同时,事务T1开始更新该行(它首先创建了版本化的行)

事务T2是否有可能读取未限制的数据? 请记住,事务T2在T1进行更新之前开始复制该行,因此该行上没有独占锁

这种情况是否可能发生?在复制该行的数据时,如果不在该行上设置共享锁,如何避免这种情况

这是否意味着使用读取提交快照/快照隔离的Sql Server根本不使用共享锁?这怎么可能

这是可能的,因为SQL Server正在读取快照,而快照根本不会经过任何更改。在当前事务开始时,它已在数据库状态下冻结,忽略其他进程的未提交事务。这是由SQL Server在tempdb中保留记录的快照()副本以供事务参考,从而更改当前的进行中数据/索引页

事务T2是否有可能读取未限制的数据?请记住,事务T2在T1进行更新之前开始复制该行,因此该行上没有独占锁

上面的叙述已经解释了这一点。但为了说明(简化):

场景1:

T1: begin tran (implicit/explicit)
T1: read value (4)
T2: read value (4) -- *
T1: update value to (8)

* - This is the committed value at the time the T2 transaction started
T1: begin tran (implicit/explicit)
T1: read value (4)
T1: update value to (8)
     version of the row with the value (4) is made
T2: read value (4) -- * from the versioned row
T1: commit

* - (4) is [still] the *committed* value at the time the T2 transaction started
场景2:

T1: begin tran (implicit/explicit)
T1: read value (4)
T2: read value (4) -- *
T1: update value to (8)

* - This is the committed value at the time the T2 transaction started
T1: begin tran (implicit/explicit)
T1: read value (4)
T1: update value to (8)
     version of the row with the value (4) is made
T2: read value (4) -- * from the versioned row
T1: commit

* - (4) is [still] the *committed* value at the time the T2 transaction started

除了逻辑锁之外,还有物理锁来保护数据库结构(在本例中,尤其是页面)。锁存保护任何与隔离级别无关的更改(位修改)。因此,即使T1不获取锁,它仍然需要在它读取的页面上获取共享锁存器,否则它将成为对它读取的结构进行低级别并发修改的牺牲品。T2只有在获得页面独占闩锁时才能修改包含其修改的行的页面。因此,T1只能在T2修改该行之前(因此该行是T1想要的)或在T2完成对该行的修改之后(现在T1必须查找该行中的前一行图像)看到该行的图像


所有隔离级别都必须遵守锁存协议,包括未提交的读取和版本控制的读取(即快照和朋友)。

我不确定在Sql Server copy 8K页面上打开快照隔离时,是否更改了某些行。您可能指的是数据库快照。而是创建存储在tempdb中的行版本。该行上的任何更新都在原始页面上进行。所以,当select开始复制数据时,update将对select正在复制的相同位置进行更改。我感兴趣的是第三种情况,当T1开始更新数据时,T2正在主动读取行。这种情况可能吗?不可能。行版本化副本是在更新数据之前创建的。在某个时间点,两个副本都包含相同的信息,这是快照隔离进程要检索的正确信息。因此,每次某个事务读取数据时,它都会在读取数据期间在完整页面上获取闩锁,并在完成后立即释放闩锁?签出