Creo que entendiste mal PREPARE TRANSACTION
.
Esa declaración finaliza el trabajo en la transacción, es decir, debe emitirse después Todo el trabajo está hecho. La idea es que PREPARE TRANSACTION
hace todo lo que podría fallar potencialmente durante una confirmación, excepto la confirmación en sí. Eso es para garantizar que un COMMIT PREPARED
posterior no puede fallar.
La idea es que el procesamiento sea el siguiente:
-
Ejecute
START TRANSACTION
en todas las bases de datos involucradas en la transacción distribuida. -
Haz todo el trabajo. Si hay errores,
ROLLBACK
todas las transacciones. -
Ejecute
PREPARE TRANSACTION
en todas las bases de datos. Si eso falla en alguna parte, ejecuteROLLBACK PREPARED
en aquellas bases de datos donde la transacción ya fue preparada yROLLBACK
en los demás. -
Una vez
PREPARE TRANSACTION
ha tenido éxito en todas partes, ejecuteCOMMIT PREPARED
en todas las bases de datos involucradas.
De esa manera, puede garantizar "todo o nada" en varias bases de datos.
Un componente importante aquí que no he mencionado es el administrador de transacciones distribuidas . Es una pieza de software que memoriza persistentemente en qué parte del procesamiento del algoritmo anterior se encuentra actualmente para que pueda limpiar o continuar con la confirmación después de un bloqueo.
Sin un administrador de transacciones distribuidas, la confirmación en dos fases no vale mucho y, de hecho, es peligrosa:si las transacciones se atascan en la fase "preparada" pero aún no están confirmadas, seguirán reteniendo bloqueos y (en el caso de PostgreSQL) bloquea el trabajo de vacío automático incluso a través de reinicios del servidor , ya que tales transacciones deben ser persistentes.
Esto es difícil de hacer bien.