I have an transaction where there are multiple operation like create table,truncate table and insert. When any of the operation fails I rollback the transaction. During this process all the tables are rollbacked except one.
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);
}
Now when 'TRUNCATE TABLE public."Products" CASCADE'
this statement is executed, it truncate 2 tables ie. ProductExt
and ProductImg
. After this statement suppose $sql4 fails to execute it throws exception and code present in catch is executed which rollbacks the transaction.
Now when rollback is completed it rollback all the tables except ProductExt
using script(PHP).
When I execute this statement on pgAdmin ie GUI of postgres it works as expected. Rollback all the tables including ProductExt
begin transaction
TRUNCATE TABLE public."Products" CASCADE
select * from "preproducts"
select * from "Products"
select * from "ProductExt"
select * from "tempproducts"
rollback
When I debugged the application found out there is FK constraint which is blocking the rollback via program.
Below is the constraint present on ProductExt
.When I remove this constraint, code works all well but I need this constraint. How can I achieve that.
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;
Also I am clear about the transaction which is working in GUI with constraint and not working using PHP script.