Проблемы с TransactionScope в ASP.NET - PullRequest
5 голосов
/ 05 мая 2011

Я создал класс для синхронизации данных между двумя различными источниками данных. Эта синхронизация делится на несколько частей (и методов). Каждый метод имеет свой собственный 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;
        }
}

Похоже, что вызова "_ TransactionsScope.Complete ()" недостаточно, чтобы убить область транзакций. Кто-нибудь знает, что я делаю неправильно?

Заранее спасибо!

UPDATE Спасибо за ваши ответы. После нескольких тестов я обнаружил, что эта проблема существует только при наличии нескольких запросов в одном методе. например:

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

Ответы [ 2 ]

5 голосов
/ 05 мая 2011

Попробуйте изменить конструктор.

using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required,
                new TransactionOptions()
                { 
                    IsolationLevel = System.Transactions.IsolationLevel.Serializable,
                    Timeout = TimeSpan.FromSeconds(120)
                }))
3 голосов
/ 06 мая 2011

Я сделал метод для создания значения максимального тайм-аута в области транзакции

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