我正在研究应用程序死锁的分析和预防措施,在那里我发现了以下事务范围的代码行:
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
那么性能会受到什么影响,因为此更改将针对应用程序中的所有选择实体命令完成?
最佳答案
如果你真的想让 IsolationLevel
为 ReadUncommitted
,那么你不应该使用 TransactionScopeOption.Suppress
。
使用 TransactionScopeOption.Suppress
不会参与任何 Transaction
并且 IsolationLevel
始终默认为数据库默认值 SQL 服务器中的 IsolationLevel.ReadCommitted
。
您需要加入一个 Ambient
事务或创建一个新事务到 IsolationLevel.ReadUncommitted
。
所以你绝对可以更改为 TransactionScopeOption.RequiredNew
以允许脏读,如果这是你想要的。
编辑
简短回答:在某种程度上
长答案:
升级到 MS DTC 是在单个 TransactionScope
中与 DB 建立多个连接的结果。
不同版本的 SQL Server 以不同的方式处理这种升级,
SQL Server 2008
不会升级,除非两个连接同时打开,而以前的版本总是会在多个连接上升级。
确保您在单个 TransactionScope
中没有多个连接,您应该没问题。但是通过查看您的代码,您已经打开了多个连接并创建了 MS DTC 升级。
使用 RequiresNew
意味着始终创建一个新的 TransactionScope
,即使这包含在 Ambient
范围内。如果处理不当,这几乎总是会造成死锁和超时问题。您最好的选择是将您访问 DB
的方式更改为更可靠的推荐模式,以避免出现问题。
关于c# - 需要帮助以使用交易范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37937499/