【问题标题】:Problems with TransactionScope in ASP.NETASP.NET 中的 TransactionScope 问题
【发布时间】:2011-05-05 15:49:57
【问题描述】:

我已经构建了一个类来在两个不同的数据源之间同步数据。这种同步分为多个部分(和方法)。每个方法都有自己的 TransactionScope,方法按顺序运行。

每次运行此代码时,我都会收到以下错误消息:

“与当前连接关联的事务已完成但尚未释放。必须释放该事务,该连接才能用于执行SQL语句。”

以下代码是带有 TransactionScope 的此类方法的示例:

private void SomeMethod()
{
        try
        {
            using (var _transactionScope = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
            {
                using (SqlConnection _connection = new SqlConnection(connectionstring))
                {
                    _connection.Open();

                    DoSomething()...
                }

                _transactionScope.Complete();
            }
        }
        catch (TransactionAbortedException e)
        {
            nlog.Error(string.Format("The transaction has been aborted: {0}", e.Message));
            throw e;
        }
        catch (Exception e)
        {
            throw e;
        }
}

似乎调用 "_transactionScope.Complete()" 不足以杀死事务范围。有没有人知道我做错了什么?

提前致谢!

更新 感谢您的回复。经过几次测试,我发现只有在一种方法中有多个查询时才会出现此问题。例如:

 try
    {
        using (TransactionScope _transactionScope = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
        {
            using (SqlConnection _connection = new SqlConnection(connectionstring))
            {
                _connection.Open();

                //new method:
                using (TransactionScope _transactionScope = new TransactionScope(TransactionScopeOption.Suppress))
                {
                    //a selectquery
                }

                //an update or insert query

            _transactionScope.Complete();
        }
    }

【问题讨论】:

  • 您的交易持续时间是否超过 10 分钟?
  • 有些事务我认为持续时间超过 10 分钟,但我通过将 'transactionOptions.Timeout' 属性和 de SqlCommand.CommandTimeout 属性设置为一小时来处理。
  • 如果事务运行的时间长于 maxTimeout,则会出现此错误。请参阅此博文:thecodesaysitall.blogspot.se/2012/04/… 或此答案:stackoverflow.com/a/10017056/205023
  • 只是一个技术说明...不要“throw e”,只使用“throw”。这会保留调用堆栈。

标签: c# sql-server transactions transactionscope


【解决方案1】:

尝试更改构造函数。

using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required,
                new TransactionOptions()
                { 
                    IsolationLevel = System.Transactions.IsolationLevel.Serializable,
                    Timeout = TimeSpan.FromSeconds(120)
                }))

【讨论】:

    【解决方案2】:

    我做了一个在事务范围内创建 Max Timeout 值的方法

    public static TransactionScope CreateDefaultTransactionScope(TransactionScopeOption option = TransactionScopeOption.Required)
        {
            var transactionOptions = new TransactionOptions();
            transactionOptions.Timeout = TimeSpan.MaxValue;
            transactionOptions.IsolationLevel = IsolationLevel.ReadCommitted;
            return new TransactionScope(option, transactionOptions);
        }
    

    然后你会使用它:

    using (TransactionScope transaction = TransactionHelper.CreateDefaultTransactionScope())
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多