Prijenos između baza podataka umire kada VPN padne, a „pokreni ponovno“ nije plan oporavka. Izdvajanje iz izvora može biti dovrš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.

Što baza podataka zapravo jamči

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 poslužitelj sam rješava svoju transakciju bez vas. Ono što se kvari jest znanje pozivatelja o ishodu.

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

Commit o kojem nikada niste čuli

Jedan način neuspjeha kažnjava naivnu logiku ponovnog pokušaja: poslužitelj izvrši commit, a potvrda nikada ne stigne do pozivatelja. Oracle to dokumentira kao problem nepoznatog ishoda i za njega pruža Transaction Guard u dokumentaciji o transakcijama. Komunikacijska greška nije dokaz da je poslani commit neuspješan, a tretiranje kao dokaza jest 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 dobiva nepromjenjiv ID serije, a cilj bilježi što je učinio 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 shemom 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 dovršetak u istoj lokalnoj transakciji.
  4. Uskladite 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čito dok omotač za ponovni pokušaj ne generira jedan automatski.

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

Preuzmite seriju, zatim primijenite

Korak primjene mora preuzeti ID serije, izvršiti poslovne promjene i zabilježiti dovrš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, točno jedno preuzimanje pobjeđuje, a drugome se to priopćuje.

Odsutan zapis o dovršetku nije dokaz da transakcija u tijeku nikada neće izvršiti commit. Preuzimanje mora serijalizirati 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.

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

Pripremno područje čini posao ponovno pokretljivim i smanjuje ovisnost o jednoj dugotrajnoj sesiji. Ne stvara jedan atomični commit preko SQL Servera, Oraclea i bilo kojeg vanjskog efekta koji posao izvršava. Ako posao to zaista treba, projektirajte i kvalificirajte podržanu distribuiranu transakciju ili proces usklađivanja, uključujući tko posjeduje rad s neizvjesnim ishodom. Sve slabije od toga pripada u runbook za usklađivanje, a ne u kôd za prijenos.

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

Povezani članci