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

Postgresql:FORBERED TRANSAKTION

Ja det er muligt, men har du virkelig brug for det?

Tænk dig om to gange, før du beslutter dig for, at dette virkelig skal være to separate databaser.

Du kan bare holde begge forbindelser åbne og ROLLBACK den første kommando, hvis den anden fejler.

Hvis du virkelig har brug for forberedte transaktioner, så fortsæt med at læse.

Med hensyn til dit skema - jeg ville bruge sekvensgeneratorer og RETURNING-klausul på databasesiden, bare for nemheds skyld.

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,
  ...
);

Nu skal du bruge noget eksternt lim - distribueret transaktionskoordinator (?) - for at få dette til at fungere korrekt.

Tricket er at bruge PREPARE TRANSACTION i stedet for COMMIT . Når begge transaktioner lykkes, skal du bruge COMMIT REPARED .

PHP proof-of-concept er nedenfor.

ADVARSEL! denne kode mangler kritiske del - det er fejlkontrol. Enhver fejl i $db2 skal fanges og ROLLBACK FORBEREDET skal udføres på $db1 Hvis du ikke fanger fejl, forlader du $db1 med fastfrosne transaktioner, hvilket er rigtig, rigtig dårligt.

<?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'" );
}
?>

Og igen - tænk dig om, før du vil bruge det. Det, Erwin foreslår, er måske mere fornuftigt.

Åh og lige en bemærkning mere... For at bruge denne PostgreSQL-funktion skal du indstille max_prepared_transactions konfigurationsvariabel til en værdi, der ikke er nul.



  1. Jobkø som SQL-tabel med flere forbrugere (PostgreSQL)

  2. forespørgsel med optællingsunderforespørgsel, indre joinforbindelse og gruppe

  3. Sådan opretter du med vilje en langvarig MySQL-forespørgsel

  4. Sådan finder du bestemte Hex-værdier og Char()-værdier i en MySQL SELECT