2015-07-20 3 views
3

Мне нужно создать простое приложение dotnet, которое будет вызывать хранимую процедуру внутри цикла (хранимая процедура принимает несколько параметров и добавляет их в таблицу). Требование состоит в том, что либо все строки вставлены, либо нет.Управление транзакциями с использованием TransactionScope()

Для обеспечения этого я использовал:

using (TransactionScope scope = new TransactionScope()) 
{ 
    foreach (EditedRule editedRules in request.EditedRules) 
    { 
      ...stored procedure call 
    } 
} 

Я никогда не использовал TransactionScope раньше, может кто-то пожалуйста, дайте мне знать, если этот код будет работать и все мои строки откатить.

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

+0

обернуть свой код в 'попробовать catch' блоки, так что вы можете осуществить откат scenarios.And убедитесь, что для вызова' scope.Complete() '. –

ответ

5

Предполагая, что ваша хранимая процедура не создает и не совершает собственную транзакцию, этот код будет работать с одним изменением: вашему коду необходимо указать код scope.Complete() до конца блока using; в противном случае транзакция будет откатываться.

using (TransactionScope scope = new TransactionScope()) { 
    foreach (EditedRule editedRules in request.EditedRules) { 
     ...stored procedure call 
    } 
    scope.Complete(); // <<== Add this line 
} 

Идея этой конструкции является то, что вызов Complete произойдет только в том случае, если блок выходит нормально, т.е. нет исключений при обработке цикла. Если выбрано исключение, scope обнаружит его и заставит транзакцию отступить.

+2

Также обратите внимание на уровень изоляции https://msdn.microsoft.com/en-us/library/ms173763.aspx –

2

Единственное, что я назвал бы о вашем коде, чтобы убедиться, сделать scope.Complete() для того, чтобы совершить сделку:

using (TransactionScope scope = new TransactionScope()) 
{ 
    foreach (EditedRule editedRules in request.EditedRules) 
    { 
     // stored proc 
    } 

    scope.Complete(); 
} 

, если какие-либо исключения происходят во время с помощью блока, то сделка будет прокатке назад.

0

Я думаю, что это то, что вы ищете:

using (var transaction = conn.BeginTransaction()) { 
    try 
    { 
     transaction.Commit(); 
    } 
    catch 
    { 
     transaction.Rollback(); 
     throw; 
    } 
}