SQL Server错误 | 快照隔离相关

3

我正在使用SQL Server 2012时遇到以下错误:

快照隔离事务访问数据库'db1'失败,因为该数据库不允许快照隔离。请使用ALTER DATABASE来允许快照隔离。

这种情况与其他博客所说的不同。我正在从另一个数据库(db1)中查询一个数据库表(db2.table1)(...使用同义词)。出错查询的简化版本如下。

select col1, col2 
from db1.tab1 t 
inner join db2.table1
where xyz = 'abc'

db1的隔离级别为默认级别(读取已提交),而db2的隔离级别为快照隔离。

以上查询在100次执行中有5次会出现上述错误消息。

此查询使用Entity Framework 6执行,并是应用程序中其他类似查询的一部分。该应用程序对所有其他操作都依赖于db2。

欢迎任何建议。

注意--> 我无法将db1的隔离级别设置为快照隔离作为解决方案。


如果交易涉及的所有数据库都不允许快照隔离,你如何/为什么期望SNAPSHOT隔离能够工作? - Dan Guzman
就像我之前提到的那样,这个程序有95次中的95次都能正常工作... - ash
1
DB2是否强制执行快照隔离(READ_COMMITTED_SNAPSHOT)?还是只是允许它存在?如果它强制执行,那么它可能无法可靠地工作。如果它是可选的,可能会出现类似于KB972915的情况,尽管这只是我个人纯粹的猜测,因为我不知道EF如何处理这种情况。 - Jeroen Mostert
只有少数交易使用快照隔离,每当从池中选择相同的连接进行上述查询时,就会引发错误。由于从池中选择连接而不重置隔离级别的行为(:按设计:),上述问题是如此随机,以至于无法预测。谢谢,这看起来像是实际的问题。 - ash
1个回答

4

回答

问题出在Entity Framework从连接池中重新使用连接的方式上。让我们以两个查询为例:

  • query1(一个将TransactionScope设置为Snapshot Isolation的查询)

  • query2(一个表示以上定义的跨数据库查询)

当query1执行时,Entity Framework会将连接(在该连接下执行query1)设置为使用快照隔离级别。并且同样的隔离级别会保留在连接中,直到另一个查询明确更改事务范围或连接被回收。请参阅此MSDN文章

在100次操作中,有5次使用了相同的连接来执行query2,这导致了使用“快照”隔离级别运行query2。由于db1未设置使用快照隔离,因此发生了错误。

需要记住一件重要的事情:

  • 当Entity Framework从连接池中重新使用连接时,它不会重置连接对象的隔离级别。为了强制使用特定的隔离级别来处理上下文,您需要显式地设置它。

希望这能帮助那些遇到类似EF相关间歇性错误的人们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接