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