PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Postgresql:PRZYGOTUJ TRANSAKCJĘ

Tak, to możliwe, ale czy naprawdę tego potrzebujesz?

Zastanów się dwa razy, zanim zdecydujesz, że to naprawdę muszą być dwie oddzielne bazy danych.

Możesz po prostu pozostawić oba połączenia otwarte i wycofać pierwsze polecenie, jeśli drugie się nie powiedzie.

Jeśli naprawdę potrzebujesz przygotowanych transakcji, czytaj dalej.

Odnośnie twojego schematu - dla wygody użyłbym generatorów sekwencji i klauzuli RETURNING po stronie bazy danych.

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,
  ...
);

Teraz będziesz potrzebować zewnętrznego kleju - koordynatora transakcji rozproszonych (?) - aby to działało poprawnie.

Sztuczka polega na użyciu PRZYGOTUJ TRANSAKCJĘ zamiast COMMIT . Następnie po pomyślnym zakończeniu obu transakcji użyj POTWIERDZENIE PRZYGOTOWANO .

Weryfikacja koncepcji PHP znajduje się poniżej.

OSTRZEŻENIE! w tym kodzie brakuje krytycznego część - czyli kontrola błędów. Dowolny błąd w $db2 powinien zostać przechwycony i ROLLBACK PREPARED powinien być wykonywany na $db1 Jeśli nie złapiesz błędów, opuścisz $db1 z zamrożonymi transakcjami, co jest naprawdę złe.

<?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'" );
}
?>

I znowu – zastanów się, zanim go użyjesz. To, co proponuje Erwin, może być bardziej rozsądne.

Aha i jeszcze jedna uwaga... Aby korzystać z tej funkcji PostgreSQL, musisz ustawić max_prepared_transactions zmienna konfiguracyjna na wartość niezerową.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Po przywróceniu PostgreSQL otrzymuję odmowę uprawnień dla relacji django_session

  2. Czy tablica zawiera wszystkie wartości NULL w PostgreSQL

  3. Jak odświeżyć wszystkie zmaterializowane widoki w Postgresql 9.3 na raz?

  4. Jak agregować pasujące pary w połączone komponenty w Pythonie?

  5. Dlaczego nie mogę użyć zmiennej w poleceniu postgres backslash (\COPY)