Prijenos između baza podataka umire kada VPN padne, a „pokreni ponovo“ nije plan oporavka. Izdvajanje iz izvora može biti završeno, cilj je možda već izvršio commit, ili se odgovor jednostavno izgubio na povratnom putu. Ta tri stanja zahtijevaju različite radnje, a klijent koji zna samo „greška“ ne može ih razlikovati.

Rješenje je arhitektonsko: dajte svakom izvršavanju trajni identitet serije i pustite baze podataka da odgovaraju na pitanja umjesto da klijent nagađa.

Šta baza podataka zapravo garantuje

SQL Server i Oracle oba daju atomičnost unutar transakcije. Nijedan ne daje atomičnost preko njih dvije. Izgubljena veza ne kvari bazu podataka i ne prisiljava na ručno vraćanje, jer server sam rješava svoju transakciju bez vas. Ono što se kvari jeste znanje pozivatelja o ishodu.

Odvojeno commitovano znači odvojeno commitovano. VPN koji nosi obje veze ne spaja dva commita u jednu radnu jedinicu.

Commit za koji nikada niste čuli

Jedan način neuspjeha kažnjava naivnu logiku ponovnog pokušaja: server izvrši commit, a potvrda nikada ne stigne do pozivatelja. Oracle to dokumentuje kao problem nepoznatog ishoda i za njega pruža Transaction Guard u dokumentaciji o transakcijama. Komunikaciona greška nije dokaz da je poslani commit neuspješan, a tretiranje kao dokaza jeste način da se serija objavi dvaput. Razlika je najvažnija na putu ponovnog pokušaja, gdje operater ima poruku o grešci i nikakav drugi signal za djelovanje.

Zato korak oporavka mora pročitati ishod iz cilja, umjesto da ga izvede iz teksta greške.

Dajte prijenosu identitet serije

Svako izvršavanje dobija nepromjenjiv ID serije, a cilj bilježi šta je uradio s tim ID-om. Životni ciklus ima četiri koraka i izgleda isto bez obzira na dobavljača:

  1. Izdvojite identificiranu, nepromjenjivu izvornu seriju sa zabilježenom šemom i granicom.
  2. Prenesite je u pripremno područje cilja i otkrijte nepotpun ili proturječan sadržaj prije nego što je proglasite spremnom.
  3. Primijenite je prema vlastitim pravilima jedinstvenosti ili zaključavanja cilja i zabilježite završetak u istoj lokalnoj transakciji.
  4. Usaglasite trajni ishod kroz podržani protokol prije potvrde ili ponovnog pokušaja.

Ponovni pokušaji koriste isti ID. Novi ID za svaki pokušaj poništava sprječavanje duplikata koje ste upravo izgradili, što zvuči očigledno dok omotač za ponovni pokušaj ne generiše jedan automatski.

ID vam također daje nešto s čime se kasnije možete usaglasiti, dugo nakon što proces klijenta nestane.

Preuzmite seriju, zatim primijenite

Korak primjene mora preuzeti ID serije, izvršiti poslovne promjene i zabilježiti završetak u jednoj lokalnoj transakciji. Ako provjeru i umetanje radite kao odvojene naredbe, vraćate utrku koju ste pokušavali ukloniti. Ako se dva radnika utrkuju, tačno jedno preuzimanje pobjeđuje, a drugom se to saopštava.

Odsutan zapis o završetku nije dokaz da transakcija u toku nikada neće izvršiti commit. Preuzimanje mora serijalizovati konkurentske pokušaje, ili protokol mora pročitati trajni ishod prije bilo kakve odluke.

Koristite podržani mehanizam baze podataka za tu serijalizaciju, umjesto petlje „provjeri pa ponovi“ u aplikacijskom kodu.

Šta dizajn još uvijek ne može obećati

Pripremno područje čini posao ponovno pokretljivim i smanjuje zavisnost od jedne dugotrajne sesije. Ne stvara jedan atomični commit preko SQL Servera, Oraclea i bilo kojeg vanjskog efekta koji posao izvršava. Ako posao to zaista treba, projektujte i kvalifikujte podržanu distribuiranu transakciju ili proces usaglašavanja, uključujući ko posjeduje rad s neizvjesnim ishodom. Sve slabije od toga pripada u runbook za usaglašavanje, a ne u kôd za prijenos.

Prihvatite prekid na tri mjesta: tokom prijenosa, tokom primjene i nakon commita ali prije potvrde. Zatim provjerite poslovni rezultat, a ne poruku klijenta, i pustite da knjiga serija kaže da li je posao nepotpun, commitovan ili još neriješen.

Povezani članci