我希望有人可以阐明我在SNAPSHOT隔离与TRUNCATE上没有想到的这种行为。
数据库:允许快照隔离= True;读取已提交快照快照= False。
Procedure1(从具有大量连接的长时间运行的复杂SELECT替换表foo的内容):
BEGIN TRAN;
TRUNCATE TABLE foo;
INSERT INTO foo SELECT...;
COMMIT;
Procedure2(从表foo中读取):
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
SELECT * FROM foo;
如果在执行Procedure2的同时正在运行Procedure1,则过程2将等待LCK_M_SCH_S(根据sp_WhoIsActive)等待,直到Procedure1完成。而当Procedure2确实完成时,它将引发此异常:
快照隔离事务在数据库'DatabaseName'中失败,因为自该事务开始以来,该语句访问的对象已由另一个并发事务中的DDL语句修改。不允许这样做,因为未对元数据进行版本控制。如果同时进行元数据更新和快照隔离,则可能导致不一致。
但是,Microsoft并未将TRUNCATE列为SNAPSHOT隔离下不允许的DDL语句:http : //msdn.microsoft.com/zh-cn/library/bb933783.aspx
显然,我并没有正确理解某些东西,因为我希望程序2的最佳情况会在TRUNCATE之前立即返回表中最近提交的数据,或者最坏的情况是被程序1阻止,然后返回程序的新内容。表。你能帮我吗?