Необходим ли явный откат транзакции?
В многочисленных примерах, где говорится о явном откате транзакций базы данных, говорится следующее:
using (var transaction = ...)
{
try
{
// do some reading and/or writing here
transaction.Commit();
}
catch (SqlException ex)
{
// explicit rollback
transaction.Rollback();
}
}
Однако я, как правило, делаю это:
using (var transaction = ...)
{
// do some reading and/or writing here
transaction.Commit();
}
Когда возникает исключение, я просто полагаюсь на неявное откат транзакций, которые не выполняются.
Есть ли какие-либо проблемы, связанные с этим неявным поведением? У кого-нибудь есть убедительная причина, почему я не должен делать это таким образом?
Ответы
Ответ 1
Нет, это не особенно необходимо, однако я могу думать о 2 причинах, почему это может быть хорошей идеей:
Некоторые могут утверждать, что использование transaction.Rollback()
делает его более ясным, при каких обстоятельствах транзакция не будет выполнена.
При работе с транзакциями важно реализовать определенные блокировки, которые будут выпущены только после откат или совершения транзакции. Если вы используете оператор using
, тогда транзакция будет отклонена при удалении транзакции, однако если по какой-то причине вам необходимо выполнить некоторую обработку ошибок внутри блока using
, может оказаться выгодным откат транзакции (удаление блокировок), прежде чем выполнять обработку сложных/временных затрат.
Ответ 2
Я вижу две проблемы с вашим использованием:
- Вы полагаетесь на метод Dispose() транзакции для отката незафиксированной транзакции, создавая зависимость от сторонней реализации IDisposable. В этом случае это незначительный риск, но это не очень хорошая практика.
- Вам не удастся зарегистрировать и/или обработать исключение. Кроме того, я бы выбрал Exception not SqlException.
Ответ 3
Думаю, на это можно ответить, что первый подход более читабельен для тех, кто поддерживает ваш код. Явный характер кодирования делает цели понятными и быстрыми. В то время как неявный откат вам понятен, и, возможно, любому, у кого есть более чем мимолетное знание обработки транзакций, может быть не для других. Тем не менее, несколько замечаний быстро исправили бы это. Единственная проблема заключается в том, что неявный откат не является документированной функцией объекта.
Итак, я бы сказал, предоставив вам комментарий к операции, и вы можете положиться на неявное действие, тогда нет веских оснований для явного подхода.
Ответ 4
Наиболее правильно написанное соединение ADO.NET будет выполнять транзакции отката, явно не переданные. Поэтому это не является строго необходимым.
Основное преимущество, которое я вижу в явном Rollback()
, называет его возможностью установить там контрольную точку и затем проверить соединение или базу данных, чтобы увидеть, что происходит. Он также более ясен будущим разработчикам кода, что происходит под разными путями выполнения.
Ответ 5
Пока транзакция полностью автономна в блоке using(), вам хорошо идти. Проблемы могут возникать и возникают, однако, если кто-то, если вы передали существующий объект транзакции от вызывающего. Но это другой сценарий...