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.