ASP.NET 中 TransactionScope 的问题

发布于 2024-11-05 10:30:29 字数 1775 浏览 1 评论 0原文

我构建了一个类来同步两个不同数据源之间的数据。这种同步分为多个部分(和方法)。每个方法都有自己的 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()" 不足以杀死 transactionscope.. 有谁知道什么我做错了吗?

提前致谢!

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

 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();
        }
    }

I've build a class to synchronize data between two different datasources. This synchronization is divided into multiple parts (and methods). Every method has his own TransactionScope and the methods are run sequentially.

Everytime I Run this code I get the following errormessage:

"The transaction associated with the current connection has completed but has not been disposed. The transaction must be disposed before the connection can be used to execute SQL statements."

The following code is an example of such a method with a 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;
        }
}

It seems that the call "_transactionScope.Complete()" isn't enough to kill the transactionscope.. Does anyone have a clue what i'm doing wrong?

Thanks in advance!

UPDATE
Thanks for your replies. After a few tests I discovered that this problem only exists when there are multiple queries in one method. for example:

 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();
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

糖果控 2024-11-12 10:30:29

尝试更改构造函数。

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

Try changing the constructor.

using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required,
                new TransactionOptions()
                { 
                    IsolationLevel = System.Transactions.IsolationLevel.Serializable,
                    Timeout = TimeSpan.FromSeconds(120)
                }))
饮惑 2024-11-12 10:30:29

我做了一种在事务范围上创建最大超时值的方法

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())

I did a method for creating a Max Timeout value on a transaction scope

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);
    }

and then you would use it:

using (TransactionScope transaction = TransactionHelper.CreateDefaultTransactionScope())
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文