我有一个事务,其中有多个操作,例如创建表,截断表和插入。当任何操作失败时,我将回滚事务。在此过程中,除一个表外,所有表都将回滚。
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中存在的代码以回滚事务。
现在回滚完成后,它会使用脚本(PHP)回滚除ProductExt
以外的所有表。
当我在pgAdmin上执行此语句时,即postgres的GUI,它按预期工作。回滚所有表,包括 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;
我也很清楚该事务在具有约束的GUI中可以正常工作,而不能在PHP脚本中正常工作。