----------------------------我是分割线-------------------------------
本文翻译自微软白皮书《SQL Server In-Memory OLTP Internals Overview》:http://technet.microsoft.com/en-us/library/dn720242.aspx
译者水平有限,如有翻译不当之处,欢迎指正。
----------------------------我是分割线-------------------------------
正如之前所介绍的 ,所有对 内存优化表数据的访问都是使用完全的乐观并发控制实现的,但也允许使用其他多个事务隔离级别进行访问。然而,在什么样的情况下允许什么样的隔离级别,看起来似乎有点混乱和不直观。需要考虑的隔离级别是那些涉及到交叉容器事务的隔离级别,这意味着任何引用内存优化表的解释型查询是来自于一个显式还是隐式的事务,或者是否处于自动提交模式下执行。在交叉容器事务中可以用于内存优化表的隔离级别取决于事务已经为SQL Server事务定义了什么隔离级别。大部分的限制都与一个事实有关,也就是即使是在同一个Transact-SQL事务中访问基于磁盘的表和内存优化表,基于磁盘的表上的操作与内存优化表上的操作各自都有它们自己的事务序列号。你可以把这种行为看作是一个较大的事务中具有两个子事务:一个子事务用于基于磁盘的表,一个子事务用于内存优化表。
首先,先笼统的看一下隔离级别的一些背景。这里不会完整的对隔离级别进行讨论,这样的讨论已经超出了本文的范围。隔离级别可以从保证的一致性属性来进行定义。最重要的属性如下:
然后,我们可以基于这些属性来定义事务隔离级别。以下列出的第一个事务隔离级别(SNAPSHOT)没有提到这些属性,但后两个都提到了。
这个隔离级别规定,在一个事务中任何语句读取的数据与事务开始时存在的数据是事务一致的版本。事务只能够识别出在事务开始前已提交数据的修改。在当前事务开始后由其他事务进行的数据修改对于在当前事务中执行的语句都是不可见的。事务中的语句获得一个已提交数据的快照与事务开始时所存在的相同。
这个隔离级别包括了SNAPSHOT隔离级别所提供的保证。此外,REPEATABLE READ还保证了读可靠性。对于事务读取的任何行,在事务提交时行还没有被其他事务更改。事务中的每一个读操作在事务结束前都是可重复的。
这个隔离级别包括了REPEATABLE READ隔离级别所提供的保证。此外,SERIALIZABLE还保证了幻影回避。在事务中的操作不会错过任何行。在快照时间和事务结束之间不会出现幻影行。幻影行符合SELECT/UPDATE/DELETE的过滤条件。如果我们能够保证,在事务结束时所有重复的读取都可以看到完全相同的数据,那么这个事务则是可序列化的。
最简单和最广泛使用的多版本并发控制的方法是快照隔离(snapshot isolation ,SI),但快照隔离并不保证可序列化,因为逻辑上读取和写入在不同时间发生,读取是在事务开始时发生,而写入是在事务结束时发生。
访问基于磁盘的表还支持READ COMMITTED隔离,它只是保证该事务将不会读取任何脏(未提交)数据。访问内存优化表需要使用上述的三种隔离级别之一。表1列出了在一个交叉容器事务中可以一起使用的隔离级别。
基于磁盘的表 |
内存优化表 |
建议 |
READ COMMITTED |
SNAPSHOT |
这是基准组合,应该用于当前使用 READ COMMITTED 的大多数场景。 |
READ COMMITTED |
REPEATABLE READ / SERIALIZABLE |
这个组合可以在数据迁移期间使用,以及用于在互操作模式下(而不是在一个本地编译存储过程中)对内存优化表的访问。 |