sql >> Databáze >  >> RDS >> PostgreSQL

Postgresql:PŘIPRAVTE TRANSAKCI

Ano, je to možné, ale opravdu to potřebujete?

Přemýšlejte dvakrát, než se rozhodnete, že to opravdu musí být dvě samostatné databáze.

Můžete ponechat obě připojení otevřená a vrátit první příkaz, pokud druhý selže.

Pokud byste skutečně potřebovali připravené transakce, pokračujte ve čtení.

Pokud jde o vaše schéma – na straně databáze bych pro pohodlí použil generátory sekvencí a klauzuli RETURNING.

CREATE TABLE tbl_album (
  id    serial PRIMARY KEY,
  name  varchar(128) UNIQUE,
  ...
);
CREATE TABLE tbl_user_album (
  id          serial PRIMARY KEY,
  album_id    bigint NOT NULL,
  ...
);

Nyní budete potřebovat nějaké externí lepidlo – koordinátor distribuovaných transakcí (?) – aby to fungovalo správně.

Trik je v použití PREPARE TRANSACTION místo COMMIT . Poté, co budou obě transakce úspěšné, použijte COMMIT PREPARED .

Doklad o konceptu PHP je níže.

UPOZORNĚNÍ! v tomto kódu chybí kritické část - to je kontrola chyb. Jakákoli chyba v $db2 by měl být zachycen a ROLLBACK PREPARED by měl být spuštěn na $db1 Pokud nezachytíte chyby, ponecháte $db1 se zmrazenými transakcemi, což je opravdu, opravdu špatné.

<?php
$db1 = pg_connect( "dbname=db1" );
$db2 = pg_connect( "dbname=db2" );
$transid = uniqid();

pg_query( $db1, 'BEGIN' );
$result = pg_query( $db1, "INSERT INTO tbl_album(name) VALUES('Absolutely Free') RETURNING id" );
$row = pg_fetch_row($result);
$albumid = $row[0];
pg_query( $db1, "PREPARE TRANSACTION '$transid'" );
if ( pg_query( $db2, "INSERT INTO tbl_user_album(album_id) VALUES($albumid)" ) ) {
    pg_query( $db1, "COMMIT PREPARED '$transid'" );
}
else {
    pg_query( $db1, "ROLLBACK PREPARED '$transid'" );
}
?>

A znovu - přemýšlejte, než to použijete. To, co navrhuje Erwin, by mohlo být rozumnější.

Jo a ještě jedna poznámka... Chcete-li používat tuto funkci PostgreSQL, musíte nastavit max_prepared_transactions konfigurační proměnná na nenulovou hodnotu.



  1. PHP zobrazované jméno přihlášeného uživatele

  2. Jak přepnout databázi pomocí PostgreSQL

  3. Chyba:Objekt třídy CI_DB_mysql_result nelze převést na řetězec

  4. vytvoření databáze v mysql z javy