sql >> Database >  >> RDS >> PostgreSQL

Postgresql:TRANSACTIE VOORBEREIDEN

Ja, het is mogelijk, maar heb je het echt nodig?

Denk twee keer na voordat je besluit dat dit echt twee aparte databases moeten zijn.

Je kunt gewoon beide verbindingen open houden en de eerste opdracht ROLLBACK als de tweede mislukt.

Als je echt voorbereide transacties nodig hebt, lees dan verder.

Wat betreft je schema - ik zou sequentiegeneratoren en RETURNING-clausule aan de databasekant gebruiken, gewoon voor het gemak.

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 heb je wat externe lijm nodig - gedistribueerde transactiecoördinator (?) - om dit goed te laten werken.

De truc is om TRANSACTIE VOORBEREIDEN in plaats van COMMIT . Nadat beide transacties zijn geslaagd, gebruikt u COMMIT PREPARED .

PHP proof-of-concept staat hieronder.

WAARSCHUWING! deze code mist de kritieke onderdeel - dat is foutcontrole. Elke fout in $db2 moet worden gevangen en ROLLBACK VOORBEREID moet worden uitgevoerd op $db1 Als je geen fouten opmerkt, laat je $db1 . achter met bevroren transacties, wat echt heel erg is.

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

En nogmaals - denk na voordat je het gaat gebruiken. Wat Erwin voorstelt, is misschien verstandiger.

Oh en nog een opmerking... Om deze PostgreSQL-functie te gebruiken, moet je max_prepared_transactions config-variabele naar een waarde die niet nul is.



  1. Externe SQL Server-sleutel naar meerdere tabellen

  2. MySQLi voorbereide verklaringen foutrapportage

  3. c# select-query naar Oracle-database gooit Custom type mapping voor ... is niet gespecificeerd of is ongeldig

  4. Hoe meerdere kolommen als één te combineren en op te maken met aangepaste tekenreeksen?