sql >> Database teknologi >  >> RDS >> PostgreSQL

Brug af tofasede commits på postgres

Jeg tror, ​​du har misforstået PREPARE TRANSACTION .

Denne erklæring afslutter arbejdet med transaktionen, det vil sige, den skal udstedes efter alt arbejdet er udført. Tanken er, at PREPARE TRANSACTION gør alt, hvad der potentielt kan fejle under en commit, bortset fra selve commit. Det er for at garantere, at en efterfølgende COMMIT PREPARED kan ikke fejle.

Tanken er, at behandlingen er som følger:

  • Kør START TRANSACTION på alle databaser, der er involveret i den distribuerede transaktion.

  • Gør alt arbejdet. Hvis der er fejl, ROLLBACK alle transaktioner.

  • Kør PREPARE TRANSACTION på alle databaser. Hvis det mislykkes nogen steder, skal du køre ROLLBACK PREPARED på de databaser, hvor transaktionen allerede var forberedt og ROLLBACK på de andre.

  • En gang PREPARE TRANSACTION er lykkedes overalt, kør COMMIT PREPARED på alle involverede databaser.

På den måde kan du garantere "alt eller intet" på tværs af flere databaser.

En vigtig komponent her, som jeg ikke har nævnt, er den distribuerede transaktionsmanager . Det er et stykke software, der vedvarende husker, hvor i ovenstående algoritme behandlingen i øjeblikket er, så den kan rydde op eller fortsætte med at begå efter et nedbrud.

Uden en distribueret transaktionsmanager er to-fase commit ikke meget værd, og det er faktisk farligt:​​Hvis transaktioner sætter sig fast i den "forberedte" fase, men ikke er commitet endnu, vil de fortsætte med at holde låse og (i tilfælde af PostgreSQL) blokerer autovakuumarbejde selv gennem servergenstarter , da sådanne transaktioner skal være vedvarende.

Det er svært at få det rigtige.




  1. Håndtering af data fra flere udvalgte felter

  2. Hvordan kan jeg indstille mysqls adgangskode i scenariet mysqld_safe kører?

  3. cx_Oracle 'ORA-01843:ikke en gyldig måned' med unicode-parameter

  4. Hvordan deaktiverer man forbindelsespool?