Опоравак учитавања из SQL Server-а у Oracle након прекида VPN-а
Прекинут VPN оставља позиваоца у неизвесности да ли је commit у Oracle-у прошао. Трајан ID серије омогућава да се издвајање, примена и усклађивање одговоре једно по једно.
Пренос између база података умире када VPN падне, а „покрени поново“ није план опоравка. Издвајање из извора може бити завршено, циљ је можда већ извршио commit, или се одговор једноставно изгубио на повратном путу. Та три стања захтевају различите радње, а клијент који зна само „грешка“ не може их разликовати.
Решење је архитектонско: дајте сваком извршавању трајан идентитет серије и пустите базе података да одговарају на питања уместо да клијент нагађа.
Шта база података заиста гарантује
SQL Server и Oracle обе дају атомичност унутар трансакције. Ниједна не даје атомичност између њих две. Изгубљена веза не квари базу података и не присиљава на ручно враћање, јер сервер сам решава своју трансакцију без вас. Оно што се квари јесте знање позиваоца о исходу.
Одвојено commit-овано значи одвојено commit-овано. VPN који носи обе везе не спаја два commit-а у једну радну јединицу.
Commit о којем никада нисте чули
Један начин неуспеха кажњава наивну логику поновног покушаја: сервер изврши commit, а потврда никада не стигне до позиваоца. Oracle то документује као проблем непознатог исхода и за њега пружа Transaction Guard у документацији о трансакцијама. Комуникациона грешка није доказ да је послати commit неуспешан, а третирање као доказа је начин да се серија објави двапут. Разлика је најважнија на путу поновног покушаја, где оператер има поруку о грешци и никакав други сигнал за деловање.
Зато корак опоравка мора прочитати исход из циља, уместо да га изведе из текста грешке.
Дајте преносу идентитет серије
Свако извршавање добија непроменљив ID серије, а циљ бележи шта је урадио са тим ID-ом. Животни циклус има четири корака и изгледа исто без обзира на добављача:
- Издвојте идентификовану, непроменљиву изворну серију са забележеном шемом и границом.
- Преносите је у припремно подручје циља и откријте непотпуни или противречни садржај пре него што је прогласите спремном.
- Примените је према сопственим правилима јединствености или закључавања циља и забележите завршетак у истој локалној трансакцији.
- Усагласите трајни исход кроз подржани протокол пре потврде или поновног покушаја.
Поновни покушаји користе исти ID. Нови ID за сваки покушај поништава спречавање дупликата које сте управо изградили, што звучи очигледно док омотач за поновни покушај не генерише један аутоматски.
ID вам такође даје нешто са чиме се касније можете усагласити, дуго након што процес клијента нестане.
Преузмите серију, затим примените
Корак примене мора преузети ID серије, извршити пословне промене и забележити завршетак у једној локалној трансакцији. Ако проверу и уметање радите као одвојене наредбе, враћате трку коју сте покушавали да уклоните. Ако се два радника такмиче, тачно једно преузимање побеђује, а другом се то саопштава.
Одсутан запис о завршетку није доказ да трансакција у току никада неће извршити commit. Преузимање мора серијализовати конкурентске покушаје, или протокол мора прочитати трајни исход пре било какве одлуке.
За ту серијализацију користите подржани механизам базе података, уместо петље „провери па понови“ у коду апликације.
Шта дизајн још увек не може да обећа
Припрема чини посао поново покретљивим и смањује зависност од једне дуготрајне сесије. Не ствара један атомични commit преко SQL Server-а, Oracle-а и било ког спољног ефекта који посао извршава. Ако посао то заиста треба, пројектујте и квалификујте подржану дистрибуирану трансакцију или процес усаглашавања, укључујући ко поседује рад са неизвесним исходом. Све слабије од тога припада runbook-у за усаглашавање, а не коду за пренос.
Прихватите прекид на три места: током преноса, током примене и након commit-а али пре потврде. Затим проверите пословни резултат, а не поруку клијента, и пустите књигу серија да каже је ли посао непотпун, commit-ован или још нерешен.