Мисля, че не сте разбрали PREPARE TRANSACTION
.
Това извлечение приключва работата по транзакцията, т.е. трябва да бъде издадено след цялата работа е свършена. Идеята е PREPARE TRANSACTION
прави всичко, което потенциално може да се провали по време на ангажимент, с изключение на самия комит. Това е да се гарантира, че последващ COMMIT PREPARED
не може да се провали.
Идеята е, че обработката е както следва:
-
Стартирайте
START TRANSACTION
на цялата база данни, участваща в разпределената транзакция. -
Върши цялата работа. Ако има грешки,
ROLLBACK
всички транзакции. -
Стартирайте
PREPARE TRANSACTION
във всички бази данни. Ако това някъде се провали, стартирайтеROLLBACK PREPARED
в тези бази данни, където транзакцията вече е била подготвена иROLLBACK
на останалите. -
Веднъж
PREPARE TRANSACTION
е успял навсякъде, стартирайтеCOMMIT PREPARED
във всички включени бази данни.
По този начин можете да гарантирате „всичко или нищо“ в няколко бази данни.
Един важен компонент тук, който не съм споменал, е мениджърът на разпределени транзакции . Това е част от софтуера, който постоянно запаметява къде в горния алгоритъм е обработката в момента, така че да може да изчисти или да продължи извършването след срив.
Без мениджър на разпределени транзакции, двуфазното ангажиране не струва много и всъщност е опасно:ако транзакциите блокират в „подготвената“ фаза, но все още не са ангажирани, те ще продължат да държат заключвания и (в случай на PostgreSQL) блокира работата на автоматичното вакуумиране дори чрез рестартиране на сървър , тъй като такива транзакции трябва да са постоянни.
Това е трудно да се разбере правилно.