Міжбазовий перенос помирає, коли VPN обривається, а «запусти ще раз» — не план відновлення. Вивантаження з джерела може бути завершене, цільова база могла вже виконати commit, або відповідь просто загубилася на зворотному шляху. Ці три стани потребують різних дій, і клієнт, який знає лише «помилка», не може їх розрізнити.

Рішення архітектурне: дайте кожному запуску стійку ідентичність пакета і дозвольте базам даних відповідати на питання, а не клієнту вгадувати.

Що база даних насправді гарантує

SQL Server і Oracle обидві забезпечують атомарність усередині транзакції. Жодна не дає атомарності між ними двома. Втрачене з'єднання не пошкоджує базу даних і не змушує до ручного відкату, бо сервер сам вирішує свою транзакцію без вас. Ламається знання сторони, що викликає, про результат.

Зафіксовано окремо означає зафіксовано окремо. VPN, що несе обидва з'єднання, не зливає два commit в одну одиницю роботи.

Commit, про який ви ніколи не чули

Один режим відмови карає наївну логіку повторів: сервер виконує commit, а підтвердження так і не доходить до сторони, що викликає. Oracle документує це як проблему невідомого результату і надає для неї Transaction Guard у документації з транзакцій. Помилка зв'язку не є доказом того, що надісланий commit не вдався, і ставитися до неї як до доказу — це шлях до подвійної публікації пакета. Ця різниця найважливіша на шляху повтору, де оператор має лише повідомлення про помилку і жодного іншого сигналу для дій.

Тому крок відновлення має читати результат із цільової бази, а не виводити його з тексту помилки.

Дайте переносу ідентичність пакета

Кожен запуск отримує незмінний ID пакета, і цільова база записує, що вона зробила з цим ID. Життєвий цикл складається з чотирьох кроків, і він виглядає однаково незалежно від постачальника:

  1. Витягніть ідентифікований, незмінний пакет джерела із записаною схемою та межею.
  2. Передайте його в підготовчу область цільової бази та виявіть неповний або суперечливий вміст, перш ніж оголосити його готовим.
  3. Застосуйте його за власними правилами унікальності або блокування цільової бази та запишіть завершення в тій самій локальній транзакції.
  4. Звірте стійкий результат через підтримуваний протокол, перш ніж підтверджувати або повторювати.

Повтори використовують той самий ID. Новий ID на кожну спробу зводить нанівець запобігання дублям, яке ви щойно побудували; це звучить очевидно, доки обгортка повтору не згенерує його автоматично.

ID також дає вам те, з чим можна звірятися пізніше, через довгий час після зникнення клієнтського процесу.

Заявіть пакет, потім застосуйте

Крок застосування має заявити ID пакета, виконати бізнес-зміни та записати завершення в одній локальній транзакції. Виконання перевірки та вставки окремими операторами повертає гонку, яку ви намагалися усунути. Якщо два працівники змагаються, перемагає рівно одна заявка, а іншому про це повідомляють.

Відсутність запису про завершення не є доказом того, що транзакція, яка виконується, ніколи не зробить commit. Заявка має серіалізувати конкуруючі спроби, або протокол має прочитати стійкий результат до будь-якого рішення.

Для цієї серіалізації використовуйте підтримуваний механізм бази даних, а не цикл «перевір і повтори» в коді застосунку.

Чого проєкт усе ще не може обіцяти

Підготовка робить роботу перезапускною і зменшує залежність від однієї довгої сесії. Вона не створює єдиний атомарний commit по SQL Server, Oracle і будь-якому зовнішньому побічному ефекту, який виконує робота. Якщо бізнесу це справді потрібно, спроєктуйте і кваліфікуйте підтримувану розподілену транзакцію або процес звіряння, включно з тим, кому належить робота з невизначеним результатом. Усе слабше за це належить до методики звіряння, а не до коду переносу.

Прийміть переривання в трьох місцях: під час переносу, під час застосування і після commit, але до підтвердження. Потім перевіряйте бізнес-результат, а не повідомлення клієнта, і дозвольте журналу пакетів сказати, чи робота незавершена, зафіксована чи досі не вирішена.

Схожі статті