我正在研究应用程序中的死锁和预防措施,我找到了以下代码行的事务范围:
var tranaction = new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted };
// TransactionScopeOption.Required changed to Suppress for 2 tier issue with MSDTC
using (var transactionScope = new TransactionScope(TransactionScopeOption.Suppress, tranaction))
{
//Select entity command.
}
我们只有一些select
实体语句,它允许脏读操作。
我已经在TransactionScopeOption
上阅读了一些资源,但在这种情况下,我在这种情况下找不到确切的TransactionScopeOption
或感觉我们可以将选项更改为RequiredNew
并让我们创建新的每次执行select命令时的事务。需要帮助才能继续前进。我们使用SQL Server作为数据源。如果我们将其更改为RequiredNew
,那么对应用程序中的所有选择实体命令进行此更改将会对性能产生什么影响?
答案 0 :(得分:4)
如果您真的想让IsolationLevel
成为ReadUncommitted
,那么您就不应该使用TransactionScopeOption.Suppress
。
TransactionScopeOption.Suppress
的使用不会参与任何Transaction
,IsolationLevel
始终默认为数据库默认值,即SQL Server中的IsolationLevel.ReadCommitted
。
您需要加入Ambient
交易或创建到IsolationLevel.ReadUncommitted
的新交易。
所以你绝对可以改为TransactionScopeOption.RequiredNew
以允许脏读,如果这是你想要的。
修改强>
简答:在某种程度上
长答案:
升级到MS DTC是在单个TransactionScope
中与DB建立多个连接的结果。
不同版本的SQL Server以不同方式处理此升级,
除非两个连接同时打开,否则SQL Server 2008
不会升级,而以前的版本将始终在多个连接上升级。
确保您在一个TransactionScope
中没有多个连接,您应该没问题。但是通过查看代码,您已经打开了多个连接并创建了MS DTC升级。
使用RequiresNew
意味着始终创建新的TransactionScope
,即使这包含在Ambient
范围内。如果处理不当,这几乎总会产生死锁和超时问题。这里,您最好的选择是更改您访问DB
到更加经过验证的推荐模式的方式,以避免出现问题。
答案 1 :(得分:2)
我不确定我理解你的问题。
如果您想询问是否 - 以编程方式 - 您可以对事务范围使用RequiredNew
范围选项,那么是的,这是可能的:
使用RequiredNew
是否有意义?最有可能的是,因为它为每个事务创建了一个事务范围始终,而不是重新使用范围。 this SO post中提到了这个缺点。