SQL savepoint – obsługa złożonych transakcji

UWAGA! Ten wpis ma już 6 lat. Pewne stwierdzenia i poglądy w nim zawarte mogą być nieaktualne.

Jakiś czas temu natknąłem się w pracy na problem obsługi złożonych transakcji.

Jako, iż SQL (a przynajmniej DBMS, z którego korzystamy) nie obsługuje zagnieżdżonych transakcji, do tej pory – dla wygody – wystarczała nam prosta modyfikacja adaptera bazodanowego, która pozwalała na “zagnieżdżanie transakcji”, a polegała jedynie na zliczaniu żądań rozpoczęcia transakcji i pilnowaniu liczby wywołań commitów/rollbacków na adapterze. W przypadku niezgodności rzeczywista transakcja (otwierana przy pierwszym żądaniu) nie była commitowana, podobnie, gdy wystąpiło przynajmniej jedno wywołanie rollback na adapterze – żadne zmiany nie były stosowane.

W rzadkich sytuacjach nietypowych, gdzie część zapytań miała zostać zastosowana, a część – w razie potrzeby – nie, obsługa odbywała się w kilku niezależnych transakcjach.

Jednak w końcu przyszedł ten moment, gdy rozbicie na wiele transakcji było praktycznie niemożliwe ze względu na złożoność procesu, który trzeba było zmodyfikować.

W skrajnym przypadku mogło to wyglądać tak:

  1. Początek procesu – wykonanie podstawowych zapytań INSERT/UPDATE
  2. Wykonanie serii zapytań INSERT/UPDATE z możliwością warunkowego ich cofnięcia.
  3. Zakończenie procesu – kolejne zapytania INSERT UPDATE.

W pewnych warunkach powinny być więc zastosowane zmiany z punku 1., cofnięte wszystkie z punktu drugiego i zastosowane zapytania z punktu trzeciego.

I tutaj przydatna okazała się klauzula SAVEPOINT, o której istnieniu wcześniej nie wiedziałem, natomiast idealnie wpasowywała się w tego typu sytuacje.

Jej zasada działania jest banalnie prosta. W momencie wywołania:

SAVEPOINT nazwa_savepointa

wewnątrz transakcji tworzony jest punkt, po którym następują kolejne zapytania i do którego można – w razie potrzeby – cofnąć się poprzez

ROLLBACK TO nazwa_savepointa

W ten sposób “zapominamy” o wykonanych po utworzeniu savepointa zapytaniach SQL, natomiast wszystkie zapytania sprzed tego czasu zostaną zastosowane, jeżeli na całej transakcji zostanie wykonany COMMIT.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Time limit is exhausted. Please reload CAPTCHA.