Postgres не может выполнить откат, Query Works в GUI, Fails в PHP Script - PullRequest
0 голосов
/ 22 января 2019

У меня есть транзакция, в которой есть несколько операций, таких как создание таблицы, усечение таблицы и вставка. Если какая-либо операция не удалась, я откат транзакции. Во время этого процесса выполняется откат всех таблиц, кроме одной.

        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.

...