PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Postgresql:SIAPKAN TRANSAKSI

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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. QueryHint ResultSetType.ForwardOnly gagal dengan Spring JPA/EclipseLink

  2. Dapatkan id sisipan terakhir setelah sisipan yang disiapkan dengan PDO

  3. Sortir/penyusunan/urutan salah dengan spasi di Postgresql 9.4

  4. Bagaimana saya bisa melakukan kurang dari, lebih besar dari di bidang JSON Postgres?

  5. Apa yang saya perlukan agar pg_dumpall berfungsi tanpa kata sandi?