我正在尝试使用System.Transaction.TransactionScope来创建一个事务来调用一些存储过程,但它似乎并没有自行清理。一旦事务完成(提交与否,并且事务范围对象被处置),后续与数据库的连接打开,其读取提交级别为serializable,而不是像通常那样提交read。
我正在为每次调用打开和关闭一个连接(关闭并返回到.NET中的正常连接池),当我完成使用它时,我错过了一些显式重置连接的方法交易?我认为System.Transaction.TransactionScope背后的想法是隐藏所有的复杂性。
所以我的代码看起来像这样:
using (var scope = new TransactionScope())
{
... make my 3 stored procedure calls ...
scope.Complete();
return returnCode;
}
我猜这是正常的做法。但是如果我查看sqlserver profiler,我可以看到用
打开连接set transaction isolation level serializable
正在搞乱后续的非事务相关数据库活动,而且显然也不那么快。我可以通过设置一个事务选项来明确地使用ReadCommited来处理这个事务,但在我看来,这不是这个操作的理想行为。
我也尝试过显式创建一个Commitabletransaction对象,创建明确的新事务,而不是使用环境事务,但仍然没有运气。
任何有关如何解决这个问题的想法都会非常感激,因为任何使用serializable连接的调用如果尝试使用readpast锁定提示都会引发错误。
答案 0 :(得分:1)
使用TransactionOptions.IsolationLevel
TransactionOptions transactionoptions1 = new TransactionOptions();
transactionoptions1.IsolationLevel = IsolationLevel.ReadCommitted;
using (var scope = new TransactionScope(TransactionScopeOption.Required, transactionoptions1))
{
... make my 3 stored procedure calls ...
scope.Complete();
return returnCode;
}
答案 1 :(得分:0)
您还应该在池中使用同一连接之间看到重置(sp_reset_connection
);那不会重置隔离级别吗?您是否尝试过再现可序列化问题(例如,锁定升级死锁)
答案 2 :(得分:0)
这是SQL Server中已知的设计决策。
此外,using new TransactionScope() Considered Harmful(06/2010;避免默认构造函数)