Обрабатывать транзакцию при вызове хранимой процедуры SQL в цикле side A C#
Я работаю над системой, которая уже разработана некоторыми другими разработчиками.
И в этой системе они вызвали хранимую процедуру, которая используется для вставки записей в боковой цикл в C# без использования пользовательских типов таблиц.
И что мне нужно сделать, так это добавить транзакцию в этот сценарий. Но проблема в том, что я понятия не имею о месте проведения сделки.
Я хотел бы знать, есть ли он в коде C#, деформирующем цикл, или внутри хранимой процедуры.
3 ответов:
Вы можете иметь его только внутри цикла C#. Транзакция, запущенная внутри процедуры , должна быть зафиксирована до завершения процедуры. SQL Server проверяет
@@TRANCOUNTдо и после выполнения процедуры, а также если результаты не совпадают, возникает исключение. Таким образом, процедура не может начать транзакцию, которая должна быть зафиксирована вызывающей стороной.Проще всего обернуть код C# в область транзакций:
using(var scope = new TransactionScope( TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = IsolationLevel.ReadCommitted })) { // Do the work here scope.Complete(); }Обратите внимание, что передача
IsolationLevel = IsolationLevel.ReadCommittedявляется критический.
В этом случае транзакция должна начинаться в коде C#, у вас есть следующие опции:
Используйте
TransactionизConnection object:using (var conn = new SqlConnection(connString)) { conn.Open(); using (IDbTransaction tran = conn.BeginTransaction()) { try { // transactional code... using (SqlCommand cmd = conn.CreateCommand()) { // Loop the Insert operation here cmd.CommandText = "INSERT Operation"; cmd.Transaction = tran as SqlTransaction; cmd.ExecuteNonQuery(); } tran.Commit(); } catch(Exception ex) { tran.Rollback(); throw; } } }- использовать
Implicit or Explicit Ambient transactionUse
TransactionScope(Implicite) Ambient transaction (при исключении это автоматический откат)using (var scope = new TransactionScope( TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = IsolationLevel.ReadCommitted })) { using (var conn = new SqlConnection(connString)) { conn.Open(); using (SqlCommand cmd = conn.CreateCommand()) { // Loop the Insert operation here cmd.CommandText = "INSERT Operation"; cmd.ExecuteNonQuery(); } } scope.Complete(); }
Использование
CommittableTransaction(явная) внешняя транзакцияvar tran = new CommittableTransaction(); using (var conn = new SqlConnection(connString)) { conn.Open(); try { conn.EnlistTransaction(tran); using (SqlCommand cmd = conn.CreateCommand()) { // Loop the Insert operation here cmd.CommandText = "INSERT Operation"; cmd.ExecuteNonQuery(); } tran.Commit(); } catch(Exception ex) { tran.Rollback(); throw; } }Для
Ambient transactions, пожалуйста, помните, что если вы откроете более одного соединения, то оно получит повышен сlocal to global transaction, таким образом, требуяMSDTC, и это оказывает влияние на производительность.Проверьте следующую ссылку:
Http://www.codeproject.com/Articles/690136/All-About-TransactionScope
В SQL SERVER
BEGIN TRY BEGIN TRAN -- DO YOUR INSERT /UPDATE /DELETE HERE COMMIT TRAN T1 END TRY BEGIN CATCH -- // ROLL BACK IF ERROR OCCURS ROLLBACK TRAN T1 END CATCHВ C#
using(TransactionScope tran = new TransactionScope()) { // DO YOUR INSERT /UPDATE /DELETE HERE tran.Complete(); }
Comments