2011-01-24 2 views

ответ

9

Commit и Откат имеют различные эффекты

  • COMMIT декрементах @@ TRANCOUNT
  • ROLLBACK толкает его обратно к нулю

Это происходит потому, что SQL Server действительно не поддерживает вложенные транзакции.

Если совершить или откат в вложенной хранимой процедуре (не сделки), то вы будете получать сообщение об ошибке 266 из-за @@ TRANCOUNT рассогласования на старте и записях

Проблема отката может быть решена с помощью SET XACT_ABORT ON, который является «автоматическим откатом» (просто) и подавляет ошибку 266.

Проблема с фиксацией ... вы не можете как таковой. Тем не менее, вы можете контролировать, где это происходит, отметив @@ TRANCOUNT на сохраненной записи proc и совершив только, если ноль.

Для правильной обработки транзакций смотрите мои ответы здесь, пожалуйста: Nested stored procedures containing TRY CATCH ROLLBACK pattern? и Have I to count transactions before rollback one in catch block in T-SQL?

2

Вы не можете зафиксировать его во вложенной процедуре, но при запуске транзакции будут завершены все вложенные процедуры внутри него. Таким образом, транзакция хороша для всех хранимых процедур, вложенных в транзакцию. В распределенных транзакциях целостность данных даже пересекает границы машины.

http://msdn.microsoft.com/en-us/library/ms188929(v=SQL.90).aspx

0

Вы должны пары до вашего НАЧАТЬ TRAN и кончает в том же SPROC

Если затем вызвать другую SPROC которая также имеет транзакции, последующее BEGIN TRAN/COMMIT TRAN пар будет увеличиваться и декремент @ @Trancount соответственно.

Сделка совершается на 'последний' COMMIT TRAN (@@ TRANCOUNT = 1)

Однако любой ROLLBACK всегда будет откат транзакции.

MSDN имеет хорошее объяснение.

0

Да, это возможно. С такими языками программирования, как C#, при передаче соединения и объекта транзакции с помощью команды. если что-либо было застигнуто как ошибочное, чем откат транзакции:

string customerConnection = "Connection"; 
     string query = "insert into temp values ('Data2','data1','data2','data3')"; 
     string query2 = "update tempcst set data = 'Hello data'"; 

     SqlConnection myConnection = new SqlConnection(customerConnection); 
     myConnection.Open(); 


     SqlTransaction myTrans = myConnection.BeginTransaction(); 

Try{ 

     int result = executeNonQuery(query, myConnection, myTrans, ""); 
     i = executeNonQuery(query2, myConnection, myTrans, ""); 
    myTrans.Commit();} 



    catch{ 
     myTrans.Rollback(); 
     myConnection.Close(); 
} 
Смежные вопросы