В документации говорится, что метод отката может быть брошен, когда транзакция не находится в состоянии ожидания (после начала транзакции и до совершения транзакции).
Я не могу найти способ проверить, может ли транзакция откат или нет. Не существует государственной собственности.
В идеале просто оберните транзакцию оператором "using" или используйте объект TransactionScope, который автоматически откатится, если будет выведено исключение, или если транзакция не будет совершена до того, как она выйдет из области действия.
В остальное время, как бы уродливо, я обычно обертываю свои откаты в пустой блок try/catch, потому что он почти всегда находится в обработчике catch, который имеет более значимое исключение. Идея состоит в том, что мы можем только откатиться, если можем, но мы не хотим начинать бросать новые исключения, если мы не можем (по каким-либо непредсказуемым причинам), потому что транзакция будет откатываться до тех пор, пока она не будет выполнена так или иначе. Вам все равно нужно попытаться правильно очистить, поэтому не нужно ждать сборщика мусора, но если вы не можете, откат не является реальной проблемой.
try
{
SqlTransaction trans = connection.BeginTransaction();
///blah blah blah
}
catch(Exception theExceptionICareAbout)
{
try
{
if(trans != null)
{
trans.Rollback();
}
}
catch {}
throw; //re-throws the meaningful exception.
}
Примечание: не пытайтесь повторить исключение (т.е. "throw theExceptionICareAbout" ), потому что это воссоздает трассировку стека. Вместо этого просто используйте "throw", который будет продолжать существующий стек исключений.
Используете ли вы объект TransactionScope в своем коде С#. Если это так, вам никогда не нужно выпускать откат. Если вы явно не совершаете транзакцию, она откатится после того, как объект области транзакции выходит из области видимости.