Czy instrukcja using wycofa transakcję bazy danych, jeśli wystąpi błąd?


83

Mam IDbTransaction w instrukcji using, ale nie jestem pewien, czy zostanie ona wycofana, jeśli w instrukcji using zostanie zgłoszony wyjątek. Wiem, że instrukcja using wymusi wywołanie metody Dispose () ... ale czy ktoś wie, czy to samo dotyczy Rollback ()?

Aktualizacja: Czy muszę również jawnie wywoływać Commit (), tak jak poniżej, czy też zajmie się tym również instrukcja using?

Mój kod wygląda mniej więcej tak:

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
Cześć, aby wyjaśnić przypadek „zatwierdzenia”. Oczywiście jest to obowiązkowe, ponieważ using () {} po prostu wywołuje metodę Dispose (). Klasa Transaction.Dispose nie mógł wiedzieć, czy powinien on popełnić albo wyrzucić, jeśli był Commit także automatyczne :)
Manitra Andriamitondra

Odpowiedzi:


104

Metoda Dispose dla klasy transakcji wykonuje wycofanie, podczas gdy klasa Oracle nie. Więc z punktu widzenia transakcji jest to zależne od implementacji.

Z usingdrugiej strony instrukcja obiektu połączenia zamknęłaby połączenie z bazą danych lub zwróciłaby połączenie z pulą po zresetowaniu. W każdym przypadku nierozliczone transakcje należy wycofać. Dlatego wyjątek nigdy nie pozostawia aktywnej transakcji.

Również tak, powinieneś zadzwonić Commit()wyraźnie.


Będzie, nawet raz to przetestowałem, jawnie zgłaszając wyjątek.
Paweł Krakowiak

1
To jest niesamowite, ale czy działa z innymi implementacjami IDbTransaction, jeśli używasz go do kompatybilności między bazami danych?
Matt Hamilton,

4
@mezoid: Commit nigdy nie nastąpi automatycznie. @matt: Powinni, zgodnie z projektem.
Sedat Kapanoglu

1
@MattHamilton, dokładnie tak, jak powiedział ssg. Sprawdziłem źródło złącza .net MySQL, zrobili to samo, jak pokazano powyżej. Rollbackjest wezwany Dispose! :)
nawfal

1
Jeśli używasz System.Data.OracleConnection, nie cofnie się on przy usuwaniu. A przynajmniej dla nas tak nie jest.
Medinoc,

20

Musisz wywołać commit. Instrukcja using nic dla ciebie nie zrobi.


5
Tak, użycie wywoła Dispose przy wyjściu, co spowoduje wywołanie Rollback, a nie Commit.
podziw

4

Uważam, że jeśli istnieje wyjątek, który Commit()nigdy nie został wywołany, transakcja zostanie automatycznie wycofana.


Tak, to jest moje zrozumienie. Transakcja trwa do momentu wywołania zatwierdzenia lub zakończenia połączenia. W tym momencie dziennik transakcji jest faktycznie aktualizowany zmianami lub wycofywany w przypadku zamkniętego połączenia (wiesz, że nigdy nie otrzymasz zatwierdzenia z zamkniętego połączenia;)).
Mike,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.