У меня есть транзакция, в которой есть несколько операций, таких как создание таблицы, усечение таблицы и вставка. Если какая-либо операция не удалась, я откат транзакции. Во время этого процесса выполняется откат всех таблиц, кроме одной.
try{
$conn = $this->_getconnetion();
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->setAttribute(PDO::ATTR_TIMEOUT, 600);
$sqlE = 'CREATE TABLE IF NOT EXISTS pext ("col1" varchar, "col2" varchar, "col3" varchar, "col4" varchar, "col5" varchar)';
$stmt = $conn->prepare($sqlE);
$stmt->execute();
$sql1 = 'CREATE TABLE IF NOT EXISTS PreProducts ( like public."Products");';
$stmt = $conn->prepare($sql1);
$stmt->execute();
$sql2 = 'CREATE TABLE IF NOT EXISTS TempTable1 AS SELECT * FROM public."Products";';
$stmt = $conn->prepare($sql2);
$stmt->execute();
$conn->beginTransaction();
$truc1 = 'TRUNCATE TABLE PreProducts';
$stmt = $conn->prepare($truc1);
$stmt->execute();
$trunc2 = 'TRUNCATE TABLE TempTable1';
$stmt = $conn->prepare($trunc2);
$stmt->execute();
$sql3 = 'INSERT INTO TempTable1 SELECT * FROM public."Products"';
$stmt = $conn->prepare($sql3);
$stmt->execute();
$trunc3 = 'TRUNCATE TABLE public."Products" CASCADE';
$stmt = $conn->prepare($trunc3);
$stmt->execute();
$sql4 = 'INSERT INTO public."Products" SELECT * FROM TempTable1 WHERE "ProductTy" = \'X\';';
$stmt = $conn->prepare($sql4);
$stmt->execute();
// Execute script to insert records for existing images only
$output = productlogoimport($conn);
$conn->commit();
$logmsg = "Import | Multi | Multi product successfully executed.";
$logged = $this->savelog($logmsg);
} catch (PDOException $e){
echo $logmsg = "Error | " .$e->getMessage();
$logged = $this->savelog($logmsg);
$conn->rollBack();
}
finally {
$this->_destroyconnection($conn);
}
Теперь, когда 'TRUNCATE TABLE public."Products" CASCADE'
этот оператор выполняется, он усекает 2 таблицы, т.е. ProductExt
и ProductImg
. Предположим, что после этого оператора $ sql4 не удалось выполнить, выдается исключение, и выполняется код, присутствующий в catch, который откатывает транзакцию.
Теперь, когда откат завершен, выполняется откат всех таблиц, кроме ProductExt
, с использованием скрипта (PHP).
Когда я выполняю это утверждение в pgAdmin, то есть в GUI postgres, оно работает как положено. Откат всех таблиц, включая ProductExt
begin transaction
TRUNCATE TABLE public."Products" CASCADE
select * from "preproducts"
select * from "Products"
select * from "ProductExt"
select * from "tempproducts"
rollback
Когда я отлаживал приложение, обнаружил, что существует ограничение FK, которое блокирует откат через программу.
Ниже приведено ограничение на ProductExt
. Когда я удаляю это ограничение, код работает хорошо, но мне нужно это ограничение. Как я могу этого достичь.
ALTER TABLE public."ProductExt"
ADD CONSTRAINT "FK_ProductExt_Products_ProductId" FOREIGN KEY ("ProductId")
REFERENCES public."Products" ("Id") MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE RESTRICT;
Также мне ясно о транзакции, которая работает в графическом интерфейсе с ограничением и не работает с использованием скрипта PHP.