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

问题描述:

有人可以帮助我理解何时使用SNAPSHOT隔离级别超过SQL Server中的READ COMMITTED SNAPSHOT?已提交的快照VS快照隔离级别

据我所知,在大多数情况下READ COMMITTED SNAPSHOT的作品,但不知道什么时候进行SNAPSHOT隔离。

感谢

+1

难怪命名事物是计算机科学中最困难的事情。很高兴你发布了这个问题。 – RBT 2016-08-24 06:44:17

+1

只需添加 - “READ_COMMITTED_SNAPSHOT”是一个数据库级选项,而“Snapshot”是可应用于特定会话或事务的隔离级别。 – RBT 2016-08-24 06:51:45

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

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

阅读此优秀的Microsoft文章:Choosing Row Versioning-based Isolation Levels。它解释了两种隔离级别的好处和成本。

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

+2

这看起来不正确。请参阅http://dba.stackexchange.com/a/54681/52708。 – 2015-01-29 01:15:20

Isolation levels table

请参见下面的例子:

提交读快照

更改数据库属性如下

ALTER DATABASE SQLAuthority 
SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE 
GO 

会议1次

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

会议2

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

结果 - 查询在第二节展示旧值(1,ONE),因为当前事务未提交。这也是避免阻塞并读取已提交数据的方法。

会议1

COMMIT 

会议2

USE SQLAuthority 
GO 
SELECT * 
FROM DemoTable 
WHERE i = 1 

结果 - 查询在第二场演出没有行,因为排在会话1.更新,因此,我们再次看到了承诺数据。

快照隔离级别

这是新的隔离级别,这是可以从SQL Server 2005起。对于此功能,应用程序需要进行更改,因为它必须使用新的隔离级别。

使用以下更改数据库设置。我们需要确保数据库中没有交易。

ALTER DATABASE SQLAuthority SET AllOW_SNAPSHOT_ISOLATION ON 

现在,我们还需要使用下面

会议1

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

会议2

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

Result-改变连接的隔离级别即使我们h ave将值改为10,我们仍然会在会话2(2,TWO)中看到旧的记录。

现在,让我们在会议上提交事务1次

会议1

COMMIT 

让我们回到会话2,然后再次运行选择。

会议2

SELECT * 
FROM DemoTable 
WHERE i = 2 

我们仍然可以看到记录,因为会话2已声明与快照隔离事务。除非我们完成交易,否则我们不会看到最新的记录。

会议2

COMMIT 
SELECT * 
FROM DemoTable 
WHERE i = 2 

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

见:SQL AuthoritySafari Books Online

+1

这个答案比所选答案更好。 – jyao 2017-05-25 23:50:29

仍然具有现实意义,从比尔的意见,我读更多和做笔记,可能是别人有用。

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

设置通过右键单击数据库“属性 - >选项 - >其他”:

并发/封闭:读取已提交快照在 [默认关闭,应该是]:

  • 使用SNAPSHOT进行选择(读取),不要等待其他人,也不要阻止他们。无代码变化
  • 影响操作
  • ALTER DATABASE SET READ_COMMITTED_SNAPSHOT [ON | OFF]
  • SELECT姓名,is_read_committed_snapshot_on FROM SYS。数据库

一致性:允许快照隔离 [默认关闭,值得商榷 - OK关闭]:

  • 允许客户机请求在不同SQL语句(交易)快照。
  • 代码必须要求“交易”快照(如SET TRANSACTION ...)
  • ALTER DATABASE SET ALLOW_SNAPSHOT_ISOLATION [ON | OFF]
  • SELECT名字,is_read_committed_snapshot_on FROM sys.databases中

正题:读取提交快照和允许快照隔离之间的另一个不是。它们是两种快照,并且可以单独打开或关闭,允许快照隔离更像是一个高级主题。允许快照隔离允许代码进一步控制快照域。

如果您考虑一行,默认情况下系统没有副本,所以如果其他人正在写入,读者必须等待,如果有其他人正在读取,作者也必须等待 - 行必须一直锁定。启用“提交读取提交快照”激活数据库以支持“快照副本”以避免这些锁定。

散漫上...

在我看来“读取已提交快照,”应该是“真”的任何正常MS SQLServer的数据库,它是一个过早的优化,这船“FALSE”默认。

但是,我被告知一行锁越来越差,不仅因为您可能在表中寻址多行,而且因为在SQL Server中,行锁使用“块”级锁实现(锁定存储器关联的随机行并且存在一个阈值,其中多个锁触发表锁定 - 可能会在忙数据库中阻塞问题的风险下进行更“乐观”的性能优化。

未对快照中可能发生的可怕“快照更新冲突”异常进行讨论,但未提供“快照读取已提交”,没有比较快照和快照读取已提交完成。

简而言之,快照隔离会在事务的开始处检索已提交数据的快照,然后对读取和写入操作使用乐观锁定。如果在尝试提交事务时发现某些其他内容更改了某些相同的数据,则数据库将回滚整个事务并在调用代码中引发导致快照更新冲突异常的错误。这是因为事务影响的数据版本在事务结束时与开始时不同。致力于

快照读不存在这个问题,因为它使用锁定在写入(悲观写),它在每个语句的统计获得的所有已提交数据的快照版本信息。

发生快照更新冲突发生在快照和不快照读取已提交的可能性是两者之间的一个非常显着的区别。