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 TRANSACTIONen todas las bases de datos involucradas en la transacción distribuida. -
Haz todo el trabajo. Si hay errores,
ROLLBACKtodas las transacciones. -
Ejecute
PREPARE TRANSACTIONen todas las bases de datos. Si eso falla en alguna parte, ejecuteROLLBACK PREPAREDen aquellas bases de datos donde la transacción ya fue preparada yROLLBACKen los demás. -
Una vez
PREPARE TRANSACTIONha tenido éxito en todas partes, ejecuteCOMMIT PREPAREDen 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.