2009-10-25 2 views
5

Я проснулся сегодня утром, пытаясь преодолеть 4 года плохой практики программирования из-за компании, над которой я работал. Одна из вещей, которые я недавно наткнулся на System.Transactions. Прочитав о них последние несколько часов, я думаю, что у меня есть адекватное понимание того, как они работают, и почему вы хотели бы их использовать. Тем не менее, все примеры, на которые я смотрел, показывают, что внутри транзакции вызывается встроенный T-SQL.Mixing System.Transactions with SqlTransactions

Я в значительной степени использую хранимые процедуры исключительно при доступе к базе данных, а существующие хранимые процедуры завернуты в их собственные SqlTransactions. Вы знаете, используя «Begin Tran», а затем откатываетесь или совершаете. Если Stored Proc вызывает другой сохраненный proc, он также создает транзакцию, а Commits пузырится, пока внешний не совершит или не откатится. Прекрасно работает.

Итак, теперь мой вопрос: если я хочу начать использовать System.Transactions в своем коде - для простых целей мониторинга последовательных задач базы данных, которые не могут быть вложены внутри одной хранимой процедуры - как это работает с существующие SqlTransactions у меня уже есть в моих хранимых процедурах?

Будет использовать System.Transactions в моем коде, просто добавьте еще один уровень защиты до того, как он будет выполнен, или потому, что я явно совершаю в своем SqlTransaction - будут ли данные сохраняться независимо от того, сделка?

+0

Принятый ответ на этот вопрос неверен. Использование транзакции Sql в System.Transaction вызывает непреднамеренное поведение (а именно, транзакция Sql НЕ участвует во внешнем System.Transaction!). Это эффективно нейтрализует вашу транзакцию. –

+0

Спасибо, что воспользовались этими исправлениями, Билл. 7 лет спустя, и я даже не могу вспомнить, выполнил ли я все, что в этом нуждалось, но хорошо иметь правильный ответ. :) – WesleyJohnson

ответ

4

Нет, транзакции System.Transactions и Sql не смешиваются.

И я цитирую «Не смешивайте их» со следующей статьи MSDN: https://msdn.microsoft.com/en-us/library/ms973865.aspx.

Sql транзакции не участвуют во внешней системе System.Transaction так, как вы хотите. Операции Sql, которые не выполняются или откаты, не будут вызывать другие действия в System.Transaction для отката.


Этого пример показывает явление:

using (var tx = new TransactionScope()) 
{ 
    using (var con = new SqlConnection($"{connectionstring}")) 
    { 
     con.Open(); 

     using (var com = new SqlCommand($"set xact_abort on; begin transaction; INSERT INTO dbo.KeyValueTable VALUES ('value1', '{Guid.NewGuid()}'); rollback;", con)) 
     { 
      // This transaction failed, but it doesn't rollback the entire system.transaction! 
      com.ExecuteNonQuery(); 
     } 

     using (var com = new SqlCommand($"set xact_abort on; begin transaction; INSERT INTO dbo.KeyValueTable VALUES ('value2', '{Guid.NewGuid()}'); commit;", con)) 
     { 
      // This transaction will actually persist! 
      com.ExecuteNonQuery(); 
     } 
    } 
    tx.Complete(); 
} 

После запуска этого примера на пустом хранилище данных вы должны заметить, что записи из второй операции Sql действительно совершенны, когда структура C# код будет означать, что их не должно быть.


Проще говоря, вы не должны смешивать их. Если вы организуете несколько транзакций Sql в приложении, вы должны просто использовать System.Transactions. К сожалению, это будет означать удаление кода транзакции из всех ваших хранимых процедур, но, увы, это необходимо, так как со смешанной моделью вы не можете гарантировать целостность ваших данных.

+0

Спасибо, я изменил принятый ответ. – WesleyJohnson

+0

Что делать, если явная транзакция ADO.Net была использована для SqlCommand и эта транзакция была зачислена в транзакцию XA (или это даже возможно)? Будет ли это отменять транзакцию XA? – STLDeveloper

-1

Работает нормально, если ваши внутренние транзакции в сохраненных процедурах совершены, все будет зафиксировано. Если один из них откатится назад, все, что находится внутри внешней трансакции, откатится. Чистая магия. :)

+0

Отлично. Это то, на что я надеялся, и это казалось логичным ответом, я просто не хотел этого делать. Очень признателен. – WesleyJohnson

+0

Это окончательно неправильно. См. Https://msdn.microsoft.com/en-us/library/ms973865.aspx –

+0

Принятый ответ был изменен. :) – WesleyJohnson

Смежные вопросы