Oui, c'est possible, mais en avez-vous vraiment besoin ?
Réfléchissez-y à deux fois avant de décider qu'il doit s'agir de deux bases de données distinctes.
Vous pouvez simplement garder les deux connexions ouvertes et ROLLBACK la première commande si la seconde échoue.
Si vous avez vraiment besoin de transactions préparées, continuez à lire.
Concernant votre schéma - j'utiliserais des générateurs de séquence et la clause RETURNING côté base de données, juste pour plus de commodité.
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,
...
);
Maintenant, vous aurez besoin d'un peu de colle externe - un coordinateur de transactions distribuées (?) - pour que cela fonctionne correctement.
L'astuce consiste à utiliser PREPARE TRANSACTION
au lieu de COMMIT
. Ensuite, une fois les deux transactions réussies, utilisez COMMIT PREPARED
.
La preuve de concept PHP est ci-dessous.
ATTENTION ! ce code manque le critique partie - qui est le contrôle d'erreur. Toute erreur dans $db2
doit être intercepté et ROLLBACK PREPARED
doit être exécuté sur $db1
Si vous n'attrapez pas d'erreurs, vous laisserez $db1
avec des transactions gelées, ce qui est vraiment, vraiment mauvais.
<?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'" );
}
?>
Et encore une fois - réfléchissez avant de l'utiliser. Ce que propose Erwin pourrait être plus sensé.
Oh et juste une note de plus... Pour utiliser cette fonctionnalité PostgreSQL, vous devez définir max_prepared_transactions
variable de configuration à une valeur non nulle.