Ya itu mungkin, tetapi apakah Anda benar-benar membutuhkannya?
Pikirkan dua kali sebelum Anda memutuskan ini benar-benar harus menjadi dua database yang terpisah.
Anda bisa membiarkan kedua koneksi tetap terbuka dan ROLLBACK perintah pertama jika yang kedua gagal.
Jika Anda benar-benar membutuhkan transaksi yang sudah disiapkan, lanjutkan membaca.
Mengenai skema Anda - Saya akan menggunakan generator urutan dan klausa RETURNING di sisi database, hanya untuk kenyamanan.
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,
...
);
Sekarang Anda memerlukan lem eksternal - koordinator transaksi terdistribusi (?) - untuk membuatnya berfungsi dengan baik.
Caranya adalah dengan menggunakan PREPARE TRANSACTION
bukannya COMMIT
. Kemudian setelah kedua transaksi berhasil, gunakan COMMIT PREPARED
.
Bukti konsep PHP ada di bawah.
PERINGATAN! kode ini tidak memiliki kritis bagian - itu adalah kontrol kesalahan. Ada kesalahan di $db2
harus ditangkap dan ROLLBACK PREPARED
harus dijalankan pada $db1
Jika Anda tidak menemukan kesalahan, Anda akan meninggalkan $db1
dengan transaksi beku yang benar-benar buruk.
<?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'" );
}
?>
Dan sekali lagi - pikirkan sebelum Anda akan menggunakannya. Apa yang Erwin usulkan mungkin lebih masuk akal.
Oh dan hanya satu catatan lagi... Untuk menggunakan fitur PostgreSQL ini, Anda perlu mengatur max_prepared_transactions
config variabel ke nilai bukan nol.