Có, nó có thể, nhưng bạn có thực sự cần nó không?
Hãy suy nghĩ kỹ trước khi bạn quyết định đây thực sự phải là hai cơ sở dữ liệu riêng biệt.
Bạn chỉ có thể giữ cả hai kết nối mở và QUAY LẠI lệnh đầu tiên nếu lệnh thứ hai không thành công.
Nếu bạn thực sự cần các giao dịch đã chuẩn bị, hãy tiếp tục đọc.
Về lược đồ của bạn - tôi sẽ sử dụng trình tạo trình tự và mệnh đề RETURNING ở phía cơ sở dữ liệu, chỉ để thuận tiện.
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,
...
);
Bây giờ bạn sẽ cần một số keo bên ngoài - điều phối viên giao dịch phân tán (?) - để làm cho việc này hoạt động bình thường.
Mẹo là sử dụng PREPARE TRANSACTION
thay vì COMMIT
. Sau đó, sau khi cả hai giao dịch thành công, hãy sử dụng COMMIT PREPARED
.
Dưới đây là bằng chứng về khái niệm PHP.
CẢNH BÁO! mã này thiếu quan trọng một phần - đó là kiểm soát lỗi. Bất kỳ lỗi nào trong $db2
nên được bắt và ROLLBACK PREPARED
sẽ được thực thi trên $db1
Nếu bạn không bắt được lỗi, bạn sẽ để lại $db1
với các giao dịch bị đóng băng thực sự rất tệ.
<?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'" );
}
?>
Và một lần nữa - hãy suy nghĩ trước khi bạn sử dụng nó. Những gì Erwin đề xuất có thể hợp lý hơn.
Ồ và chỉ một lưu ý nữa ... Để sử dụng tính năng PostgreSQL này, bạn cần đặt max_prepared_transactions
biến cấu hình thành giá trị khác không.