读取已提交的快照VS快照隔离级别

有人可以帮我理解什么时候使用SQL Server中的READ COMMITTED SNAPSHOT SNAPSHOT隔离级别?

我明白在大多数情况下,READ COMMITTED SNAPSHOT工作,但不知道什么时候进行SNAPSHOT隔离。

谢谢

READ COMMITTED SNAPSHOT乐观读取和悲观写入。 相比之下, SNAPSHOT乐观的读取和乐观的写道。

对于大多数需要行版本控制的应用程序,Microsoftbuild议使用READ COMMITTED SNAPSHOT

阅读这篇出色的Microsoft文章: select基于行版本控制的隔离级别 。 它解释了两个隔离级别的好处和成本。

这里是一个更彻底的: http : //msdn.microsoft.com/en-us/library/ms345124(SQL.90).aspx

隔离级别表

看下面的例子:

读取提交的快照

如下所示更改数据库属性

 ALTER DATABASE SQLAuthority SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE GO 

第一部分

 USE SQLAuthority GO BEGIN TRAN UPDATE DemoTable SET i = 4 WHERE i = 1 

第二部分

 USE SQLAuthority GO BEGIN TRAN SELECT * FROM DemoTable WHERE i = 1 

结果 – 由于当前事务未提交,因此会话2中的查询显示旧值(1,ONE)。 这也是避免阻塞和读取已提交数据的方法。

第一部分

 COMMIT 

第二部分

 USE SQLAuthority GO SELECT * FROM DemoTable WHERE i = 1 

结果 – 会话2中的查询显示没有行,因为行在会话1中更新。所以我们再次看到提交的数据。

快照隔离级别

这是从SQL Server 2005开始提供的新的隔离级别。 对于此function,应用程序需要进行更改,因为它必须使用新的隔离级别。

使用下面的数据库设置更改 我们需要确保数据库中没有事务。

 ALTER DATABASE SQLAuthority SET AllOW_SNAPSHOT_ISOLATION ON 

现在,我们还需要使用下面的方法来改变连接的隔离级别

第一部分

 USE SQLAuthority GO BEGIN TRAN UPDATE DemoTable SET i = 10 WHERE i = 2 

第二部分

 SET TRANSACTION ISOLATION LEVEL SNAPSHOT GO USE SQLAuthority GO BEGIN TRAN SELECT * FROM DemoTable WHERE i = 2 

结果 – 即使我们已经将值更改为10,我们仍然会在会话2(2,TWO)中看到旧logging。

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

第一部分

 COMMIT 

让我们回到会话2并再次运行select。

第二部分

 SELECT * FROM DemoTable WHERE i = 2 

我们仍然会看到logging,因为会话2已经说明了与快照隔离的事务。 除非我们完成交易,否则我们不会看到最新的logging。

第二部分

 COMMIT SELECT * FROM DemoTable WHERE i = 2 

现在,我们不应该看到行已经更新。

请参阅: SQL权威 , Safari联机丛书

仍然相关,从比尔的评论开始,我读了更多,并提出可能对其他人有用的笔记。

默认情况下,单个语句(包括“SELECT”)在“提交”数据(READ COMMITTED)上工作,问题是:他们是否等待数据“空闲”并在读取时阻止其他人工作?

通过右键单击DB“Properties – > Options – > Miscellaneous”来设置:

并发/阻塞:读取提交快照开启 [默认closures,应该打开]:

  • 使用SNAPSHOTselect(读取),不要等待其他人,也不要阻止他们。
  • 效果操作无需更改代码
  • ALTER DATABASE SET READ_COMMITTED_SNAPSHOT [ON | OFF]
  • SELECT名称,is_read_committed_snapshot_on FROM sys.databases

一致性:允许快照隔离 [默认closures,可辩论 – closures]:

  • 允许客户端跨SQL语句(事务)请求SNAPSHOT。
  • 代码必须请求“事务”快照(如SET TRANSACTION …)
  • ALTER DATABASE SET ALLOW_SNAPSHOT_ISOLATION [ON | OFF]
  • SELECT名称,is_read_committed_snapshot_on FROM sys.databases

对于这个问题:读取提交的快照和允许快照隔离之间不是一个另一个。 它们是两种快照,可以单独打开或closures,允许快照隔离是一个高级主题。 允许快照隔离允许代码进一步控制快照区域。

这个问题似乎很清楚,如果你考虑一行:在默认情况下,系统没有副本,所以读者必须等待,如果有其他人正在写,并且作家还必须等待,如果其他人正在阅读 – 该行必须locking所有时间。 启用“提交读取提交快照”激活数据库以支持“快照副本”以避免这些locking。

在…上…

在我看来,“Read Committed Snapshot On”对于任何普通的MS SQLServer数据库都应该是“TRUE”,并且默认情况下它是“FALSE”的过早优化。

但是,我被告知一行锁越来越差,不仅因为你可能在表中寻址多行,而且因为在SQL Server中,行锁使用“块”级锁(locking与存储邻近关联的随机行)来实现,有一个阈值,其中多个锁触发表锁 – 大概是更乐观的性能优化,在忙数据库中阻塞问题的风险。