根据BOL,“SNAPSHOT
指定事务中任何语句读取的数据 将是事务一致的数据版本 在交易开始时存在“
然而,这并不是我所观察到的。考虑一下:
在第一个标签中,运行:
CREATE TABLE dbo.TestTable(i INT); GO
INSERT INTO dbo.TestTable(i)VALUES(1);
在另一个(第二个)标签中,运行:
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
BEGIN TRANSACTION ;
请注意,此时TestTable中只有一行。 再次转到第一个标签,再添加一行:
INSERT INTO dbo.TestTable(i) VALUES(2);
返回第二个标签并运行选择:
SELECT i FROM dbo.TestTable;
i
-----------
1
2
(2 row(s) affected)
对我而言,看起来BOL可能是错的。你觉得怎么样?
答案 0 :(得分:1)
您正在看第二行,因为当您开始交易时,您没有在桌面上放置任何锁。
如果SQL每次启动事务时都要对所有数据进行一致的复制,那么将会有大量的IO。尝试在事务中查询表,然后添加新行,然后再次查询表。
(我会对此进行测试,但我目前没有方便的盒子进行测试。)
答案 1 :(得分:1)
同样来自BOL:
交易从BEGIN开始 执行TRANSACTION语句。 但是,交易顺序 号码从第一次读取开始或 在BEGIN之后写入操作 交易声明。
因此,您的文档存储“一致视图”与您发出第一次读取或写入时的事务状态一致(因为版本存储访问条件基于您的事务序列号) :
每个版本都标有 交易序列号 进行更改的交易。 ... 当快照事务读取具有版本链的行时, 数据库引擎遵循链和 检索行所在的行 交易序列号是:
- 最接近但低于快照的序列号 阅读行的交易。
- 不在快照时活动的事务列表中 交易开始。
...
...读取提交的事务读取 最新交易序列号 为该实例发布的 数据库引擎。这是 用于的交易序列号 选择正确的行版本 那句话。
所以你看,版本商店访问中没有任何地方使用的事务时间,总是关于序列号。序列号从第一次读/写开始,如记录所示。您应该在SET TRANSACTION ISOLATION BOL主题和其他建议在版本存储中使用事务 time 的地方提交错误。
答案 2 :(得分:0)
当您尝试对事务资源执行某种访问时,您的事务“启动”。这可能是一个表,一个数据库用户,甚至是参与分布式事务的另一个系统上的资源。
这使得它非常开放。如果您在BEGIN TRANSACTION语句之后立即从表中选择,我怀疑您会看到相同的行为。如果您在分布式事务中访问某些资源,我也怀疑您会看到与现在相同的行为。如果您执行类似“SELECT 1”的操作,我会打赌(但不超过1美元)您会看到您现在看到的内容,因为这不会影响任何交易资源。