Данные зафиксированы, хотя System.Transactions.TransactionScope.Commit () не вызывается - PullRequest
5 голосов
/ 10 ноября 2009

При каких обстоятельствах код, завернутый в System.Transactions.TransactionScope, может по-прежнему фиксироваться, даже если было сгенерировано исключение, и для самой внешней области никогда не вызывался коммит?

Существует метод верхнего уровня, заключенный в using (var tx = new TransactionScope()), который вызывает методы, которые также используют TransactionScope таким же образом.

Я использую типизированные наборы данных со связанными табличными адаптерами. Может ли быть так, что команды в адаптере по какой-то причине не задействованы? Кто-нибудь из вас знает, как можно проверить, зачисляются ли они в окружающий TransactionScope или нет?

Ответы [ 3 ]

8 голосов
/ 10 ноября 2009

Ответ оказался потому, что я создавал TransactionScope объект после SqlConnection объекта.

Я перешел от этого:

using (new ConnectionScope())
using (var transaction = new TransactionScope())
{
    // Do something that modifies data

    transaction.Complete();
}

к этому:

using (var transaction = new TransactionScope())
using (new ConnectionScope())
{
    // Do something that modifies data

    transaction.Complete();
}

и теперь это работает!

Итак, мораль этой истории состоит в том, чтобы создать свою TransactionScope первую .

2 голосов
/ 10 ноября 2009

Очевидный сценарий может быть в том случае, когда явно указывается новая (RequiresNew) / нулевая (Suppress) транзакция, но есть также сбой времени ожидания / отмены привязки, который может привести к тому, что соединения пропустят транзакцию. См. ранее пост (исправление - просто изменение строки подключения) или полная информация .

0 голосов
/ 23 мая 2014

Знайте, как работает TransactionScope:
Он устанавливает свойство System.Transactions.Transaction.Current в начале использования scope и затем возвращает его к предыдущему значению в конце использования scope.

Предыдущее значение зависит от того, где объявлена ​​данная область. Это может быть в другом объеме.


Вы можете изменить код следующим образом:

using (var sqlConnection = new ConnectionScope())
using (var transaction = new TransactionScope())
{
    sqlConnection.EnlistTransaction(System.Transactions.Transaction.Current);
    // Do something that modifies data
    transaction.Complete();
}

Я показываю эту возможность для тех, кто имеет более сложный код и не может просто изменить код, чтобы сначала открыть соединение с БД.

...