Co się stanie, jeśli nie zatwierdzisz transakcji w bazie danych (powiedzmy, SQL Server)?


108

Załóżmy, że mam zapytanie:

begin tran
-- some other sql code

A potem zapominam o zatwierdzeniu lub wycofaniu.

Co się stanie, jeśli inny klient spróbuje wykonać zapytanie?

Odpowiedzi:


148

Dopóki nie ZATWIERDZISZ ani nie ROLLBACK transakcji, jest ona nadal „uruchomiona” i potencjalnie zawiera blokady.

Jeśli klient (aplikacja lub użytkownik) zamknie połączenie z bazą danych przed zatwierdzeniem, wszelkie nadal działające transakcje zostaną wycofane i zakończone.


1
mmm, ok, rozumiem, że to tworzy jakiś rodzaj blokady. Nie byłem pewien, czy zamknięcie połączenia rzeczywiście wyprowadzi mnie z tego stanu. problem polegał na tym, że otrzymywałem błąd, kiedy próbowałem popełnić błąd. teraz zamknąłem połączenie i wszystko działało.
Charbel

12
Uwaga dodatkowa: Jeśli używasz Management Studio, zamknięcie okna zapytania spowoduje zamknięcie połączenia
Joe Phillips,

3
@BradleyDotNET: tak, zdecydowanie
marc_s

2
Należy pamiętać, że SQL Server Management Studio domyślnie zatwierdza automatycznie po zamknięciu okna zapytania / połączenia.
Nuno

1
Należy pamiętać, że gdy klient zamyka połączenie, gdy transakcja jest aktywna, nie zawsze jest ona wycofywana - zależy to od klienta i bazy danych. Np. Gdy aplikacja Java zamyka połączenie z bazą danych Oracle, wszelkie otwarte połączenia są automatycznie zatwierdzane.
AviD,

38

Możesz tego spróbować samemu, co powinno pomóc ci poczuć, jak to działa.

Otwórz dwa okna (zakładki) w Management Studio, każde z nich będzie miało własne połączenie z sql.

Teraz możesz rozpocząć transakcję w jednym oknie, zrobić coś takiego jak wstawianie / aktualizowanie / usuwanie, ale jeszcze nie zatwierdzać. następnie w drugim oknie możesz zobaczyć, jak wygląda baza danych spoza transakcji. W zależności od poziomu izolacji tabela może być zablokowana do momentu zatwierdzenia pierwszego okna lub możesz (nie) zobaczyć, co zrobiła do tej pory inna transakcja itp.

Baw się różnymi poziomami izolacji i nie wyświetlaj podpowiedzi, aby zobaczyć, jak wpływają one na wyniki.

Zobacz także, co się stanie, gdy wyrzucisz błąd w transakcji.

Bardzo ważne jest, aby zrozumieć, jak to wszystko działa, w przeciwnym razie niejednokrotnie będziesz zaskoczony tym, co robi sql.

Baw się dobrze! GJ.


ok, ale czy transakcja zostanie zapisana w celu zalogowania przynajmniej przed wydaniem zatwierdzenia? Na przykład, powiedzmy, że chcę rozpocząć transakcję, uruchom polecenie wstawiania i „zrób coś innego” przed wykonaniem zatwierdzenia. czy moje polecenie wstawiania zostanie zapisane w celu logowania? w ten sposób, jeśli serwer ulegnie awarii przed wykonaniem zatwierdzenia… może wrócić do miejsca, w którym był i mogę po prostu wydać zatwierdzenie później (za każdym razem, gdy skończę robić „coś innego”).
user1870400

16

Transakcje mają przebiegać całkowicie lub wcale. Jedynym sposobem zakończenia transakcji jest zatwierdzenie, każdy inny sposób spowoduje wycofanie.

Dlatego jeśli rozpoczniesz, a następnie nie zatwierdzisz, zostanie wycofana po zamknięciu połączenia (ponieważ transakcja została zerwana bez oznaczenia jako zakończona).


Tak powinno być, ale nie zawsze tak jest.
FalcoGer

... takie jak MySQL MyISAM, który nie obsługuje transakcji, jasne.
Piskvor opuścił budynek

3

zależy od poziomu izolacji transakcji przychodzącej.

Wyjaśnienie izolacji transakcji SQL


6
Zachowanie transakcji nie zależy od poziomu izolacji. Liczba blokad, które mogą powodować, tak.
marc_s

Jestem prawie pewien, jakie dane można odczytać przez połączenie, jest zdecydowanie zależne od poziomu izolacji. Jeśli masz izolację ustawioną na READ UNCOMMITTED, możesz odczytać dane, które nie zostały jeszcze zatwierdzone i mogą w rzeczywistości zostać wycofane w pewnym momencie ścieżki, ale zapewnia to brak blokady. Jeśli jako poziom izolacji ustawiłeś READ COMMITTED, nie możesz odczytać niezatwierdzonych wierszy - drugi klient zawiesi się, chyba że użyjesz SNAPSHOT.
Xhalent

2

Kiedy otwierasz transakcję, nic samo się nie blokuje. Ale jeśli wykonasz jakieś zapytania wewnątrz tej transakcji, w zależności od poziomu izolacji, niektóre wiersze, tabele lub strony zostaną zablokowane, więc wpłynie to na inne zapytania, które próbują uzyskać do nich dostęp z innych transakcji.


1

Przykład transakcji

rozpocznij tran t

Twoje instrukcje sql

jeśli wystąpił błąd rollback tran tt else commit tran tt

Dopóki nie wykonałeś commita trans tt, dane nie zostaną zmienione


1
Zwróć uwagę, że nazewnictwo transakcji jest nie tylko zbędne w MS SQL, ale może dawać fałszywe poczucie kontroli. BEGIN TRAN X ... BEGIN TRAN Y ... ROLLBACK Yna przykład nie działa. Zobacz stackoverflow.com/questions/1273376/…

0

Oprócz potencjalnych problemów z blokowaniem, które możesz spowodować, zauważysz również, że dzienniki transakcji zaczynają rosnąć, ponieważ nie można ich obciąć poza minimalną wartość LSN dla aktywnej transakcji, a jeśli używasz izolacji migawki, Twój magazyn wersji w tempdb będzie się powiększał podobne powody.

Możesz użyć, dbcc opentranaby zobaczyć szczegóły najstarszej otwartej transakcji.


0

Każda niezakończona transakcja pozostawi serwer zablokowany, a inne zapytania nie będą wykonywane na serwerze. Musisz albo wycofać transakcję, albo ją zatwierdzić. Zamknięcie SSMS spowoduje również zakończenie transakcji, co pozwoli na wykonanie innych zapytań.


-4

Zachowanie nie jest zdefiniowane, więc musisz jawnie ustawić zatwierdzenie lub wycofanie:

http://docs.oracle.com/cd/B10500_01/java.920/a96654/basic.htm#1003303

„Jeśli tryb automatycznego zatwierdzania jest wyłączony i połączenie zostanie zamknięte bez jawnego zatwierdzania lub cofania ostatnich zmian, wykonywana jest niejawna operacja COMMIT”.

Hsqldb dokonuje wycofania

con.setAutoCommit(false);
stmt.executeUpdate("insert into USER values ('" +  insertedUserId + "','Anton','Alaf')");
con.close();

wynik jest

2011-11-14 14: 20: 22,519 główne INFO [SqlAutoCommitExample: 55] [AutoCommit włączone = false] 2011-11-14 14: 20: 22,546 główne INFO [SqlAutoCommitExample: 65] [Znaleziono 0 # użytkowników w bazie danych]


2
Może tak być w przypadku Oracle (nie mam pojęcia), ale pytający pyta o MS-SQL
PaulG

Pierwszy cytat dotyczy sterownika JDBC, a nie serwera.
djechlin
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.