Ja det är möjligt, men behöver du verkligen det?
Tänk efter två gånger innan du bestämmer dig för att detta verkligen måste vara två separata databaser.
Du kan bara hålla båda anslutningarna öppna och ROLLBACK det första kommandot om det andra misslyckas.
Fortsätt läsa om du verkligen behöver förberedda transaktioner.
Angående ditt schema - jag skulle använda sekvensgeneratorer och RETURNING-satsen på databassidan, bara för bekvämlighets skull.
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 behöver du lite externt lim - distribuerad transaktionskoordinator (?) - för att få detta att fungera korrekt.
Tricket är att använda FÖRBERED TRANSAKTION
istället för COMMIT
. Sedan efter att båda transaktionerna har lyckats, använd COMMIT REPARED
.
PHP proof-of-concept finns nedan.
VARNING! den här koden saknar kritiska del - det är felkontroll. Eventuella fel i $db2
ska fångas upp och ÅTERBAKNING FÖRBEREDAS
bör köras på $db1
Om du inte upptäcker fel lämnar du $db1
med frysta transaktioner vilket är riktigt, riktigt dåligt.
<?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'" );
}
?>
Och återigen - tänk efter innan du kommer att använda den. Det Erwin föreslår kan vara mer förnuftigt.
Åh och bara en anteckning till... För att använda den här PostgreSQL-funktionen måste du ställa in max_prepared_transactions
konfigurationsvariabel till ett värde som inte är noll.