Будет ли оператор using выполнять откат транзакции базы данных в случае возникновения ошибки?

83

У меня есть IDbTransaction в операторе using, но я не уверен, будет ли он отменен, если в операторе using возникнет исключение. Я знаю, что оператор using принудительно вызовет Dispose () ... но знает ли кто-нибудь, верно ли то же самое для Rollback ()?

Обновление: Кроме того, мне нужно явно вызывать Commit (), как показано ниже, или об этом также позаботится оператор using?

Мой код выглядит примерно так:

using Microsoft.Practices.EnterpriseLibrary.Data;

...

using(IDbConnection connection = DatabaseInstance.CreateConnection())
{
    connection.Open();

    using(IDbTransaction transaction = connection.BeginTransaction())
    {
       //Attempt to do stuff in the database
       //potentially throw an exception
       transaction.Commit();
    }
}
мезоид
источник
3
Привет, просто чтобы прояснить случай "фиксации". Конечно, это обязательно, потому что using () {} просто вызывает метод Dispose (). Класс Transaction.Dispose не мог знать, следует ли ему зафиксировать или удалить, если
фиксация
См. Также stackoverflow.com/questions/6418992/…
nawfal 01

Ответы:

104

Метод Dispose для класса транзакции выполняет откат, а класс Oracle - нет. Так что с точки зрения транзакции это зависит от реализации.

С usingдругой стороны, оператор для объекта соединения либо закроет соединение с базой данных, либо вернет соединение с пулом после его сброса. В любом случае невыполненные транзакции следует откатить. Вот почему исключение никогда не оставляет активной транзакции.

Кроме того, да, вы должны звонить Commit()явно.

Седат Капаноглу
источник
Будет, я даже однажды протестировал это, явно вызвав исключение.
Павел Краковяк,
1
Это является удивительным, но это работает для других реализаций IDbTransaction , если вы используете его для кросс-совместимость дб?
Мэтт Гамильтон,
4
@mezoid: Коммит никогда не произойдет автоматически. @matt: По замыслу, должны.
Седат Капаноглу,
1
@MattHamilton в точности так, как сказал ssg. Я проверил источник коннектора MySQL .net, они сделали то же самое, что показано выше. Rollbackвызывается Dispose! :)
nawfal 01
1
Если вы используете System.Data.OracleConnection, он не будет откатываться при удалении. По крайней мере, для нас это не так.
Medinoc
20

Вы должны вызвать фиксацию. Оператор using ничего за вас не зафиксирует.

джхале
источник
5
Да, использование вызовет Dispose при выходе, который вызовет Rollback, а не Commit.
трепет
4

Я считаю, что если есть исключение, которое Commit()никогда не было вызвано, транзакция автоматически откатится.

Томми Хуэй
источник
Да, это мое понимание. Транзакция живет до тех пор, пока не будет вызвана фиксация или не завершится соединение. В этот момент журнал транзакций фактически обновляется с учетом изменений или откатывается в случае закрытого соединения (вы знаете, что вы никогда не получите фиксацию из закрытого соединения;)).
Mike