PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Postgresql:ПОДГОТВЕТЕ ТРАНЗАКЦИЯТА

Да, възможно е, но наистина ли ви трябва?

Помислете два пъти, преди да решите, че това наистина трябва да са две отделни бази данни.

Можете просто да държите двете връзки отворени и да ROLLBACK първата команда, ако втората е неуспешна.

Ако наистина имате нужда от подготвени транзакции, продължете да четете.

Относно вашата схема - бих използвал генератори на последователности и клауза RETURNING от страна на базата данни, само за удобство.

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

Сега ще ви трябва малко външно лепило - координатор на разпределени транзакции (?) - за да работи правилно.

Номерът е да използвате ПОДГОТВЯНЕ НА ТРАНЗАКЦИЯ вместо КОМИТ . След това, след като и двете транзакции успеят, използвайте COMMIT PREPARED .

PHP доказателство за концепцията е по-долу.

ПРЕДУПРЕЖДЕНИЕ! в този код липсва критичното част - това е контрол на грешките. Всяка грешка в $db2 трябва да бъде уловен и ПОДГОТВЕН ЗА ВЪРТАНЕ трябва да се изпълни на $db1 Ако не улавяте грешки, ще напуснете $db1 със замразени транзакции, което е наистина, наистина лошо.

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

И отново - помислете преди да го използвате. Това, което Ервин предлага, може да е по-разумно.

О, и само още една бележка... За да използвате тази функция на PostgreSQL, трябва да зададете max_prepared_transactions конфигурационната променлива на ненулева стойност.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Създаване на SQL функция, препращаща към таблица или колона, която не съществува (все още)

  2. Грешка:Трябва да инсталирате поне един пакет postgresql-client-<version>

  3. ГРЕШКА:входните параметри след един със стойност по подразбиране също трябва да имат стойности по подразбиране в Postgres

  4. Изпълнението на SQL скрипт през psql дава синтактични грешки, които не се появяват в PgAdmin

  5. Как мога да конфигурирам PostgreSQL да използва Windows Authentication?