首页 > 解决方案 > php事务错误,我总是得到一个回滚错误

问题描述

我试图一次更新 2 个表。根据我的研究,我必须为此使用交易:

protected function myUpdateFunction(){
        try{
            $this->connect()->beginTransaction();

        $itemID = filter_input(INPUT_POST, 'updateItemID');
        $itemName = filter_input(INPUT_POST, 'updateItemName');
        $itemDescription = filter_input(INPUT_POST, 'updateItemDescription');
        $itemPrice = filter_input(INPUT_POST, 'updateItemPrice');
        $itemStock = filter_input(INPUT_POST, 'updateItemStock');
        $updateItemBtn = filter_input(INPUT_POST, 'updateItemBtn');

        $sql = "UPDATE oopphp_items SET itemName = ?, itemDescription = ?, itemPrice = ?, itemStock = ? WHERE itemID = ?";
        $stmt = $this->connect()->prepare($sql);
        $stmt->bindParam(1, $itemName, PDO::PARAM_STR);
        $stmt->bindParam(2, $itemDescription, PDO::PARAM_STR);
        $stmt->bindParam(3, $itemPrice, PDO::PARAM_STR);
        $stmt->bindParam(4, $itemStock, PDO::PARAM_INT);
        $stmt->bindParam(5, $itemID, PDO::PARAM_INT);
        $stmt->execute();


        //wishlist
        $itemID_fk = filter_input(INPUT_POST, 'updateItemID');
        $itemName_fk = filter_input(INPUT_POST, 'updateItemName');
        $itemDescription_fk = filter_input(INPUT_POST, 'updateItemDescription');
        $itemPrice_fk = filter_input(INPUT_POST, 'updateItemPrice');

        $sql = "UPDATE oopphp_wishlist SET itemName_fk = ?, itemDescription_fk = ?, itemPrice_fk = ? WHERE itemID_fk = ?";
        $stmt = $this->connect()->prepare($sql);
        $stmt->bindParam(1, $itemName_fk, PDO::PARAM_STR);
        $stmt->bindParam(2, $itemDescription_fk, PDO::PARAM_STR);
        $stmt->bindParam(3, $itemPrice_fk, PDO::PARAM_STR);
        $stmt->bindParam(4, $itemID_fk, PDO::PARAM_INT);
        $stmt->execute();

        $this->connect()->commit();
        }
        catch(Exception $e){
                echo $e->getMessage();
                $this->connect()->rollBack();

        }
    }

我收到以下错误:

致命错误:未捕获的 PDOException:没有活动事务

当我试图寻找答案时,他们都说要把它放在一个 try-catch 中,我已经这样做了。我能找到的所有例子都是这样的。如此处所示:PHP PDO - 没有活动事务

我还发现有些人建议将这些添加到数据库文件中:

$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute( PDO::ATTR_EMULATE_PREPARES, false);
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, FALSE);

这也没有做任何事情。

现在,如果我只是删除 catch() 中的代码,那么错误就会消失,我的两个更新查询都可以工作。

我能发现的唯一区别是所有示例都没有将它们的数据库连接作为函数。

所以我在哪里:

$this->connect()->beginTransaction();

他们是这样:

$pdo->beginTransaction();

commit() 和 rollBack() 显然相同。虽然我无法想象这是问题所在。特别是当我删除 catch() 内容时它可以完美运行。

这是我从以下获得代码的地方:https ://thisinterestsme.com/php-pdo-transaction-example/

除了connect() vs $pdo,我似乎有相同的代码。

我的连接功能:

protected function connect(){
        try{
            $dsn = 'mysql:host=' . $this->DB_HOST . ';dbname=' . $this->DB_NAME;
            $pdo = new PDO($dsn, $this->DB_USER, $this->DB_PASS);

            //setting default fetch mode
            $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

            //setting errors for exceptions for try/catch
            $pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

            $pdo->setAttribute( PDO::ATTR_EMULATE_PREPARES, false);
            $pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, false);
            return $pdo;
        }
        catch(PDOException $error){
            echo 'Connection error: ' . $error->getMessage();
        }
        finally{
            //$pdo = null;
        }
    }

我在评论的帮助下修复了它,如果有人稍后看到这个,最后的注释:我提到的这一行:$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, FALSE);

成功了,所以我的 CRUD 不再起作用了。其他 2 setAttribute() 目前没有导致任何错误。

标签: phppdo

解决方案


当你调用 时connect(),你每次都会得到一个不同的 PDO 对象。因此,

$this->connect()->beginTransaction(); // pdo object 1

$this->connect()->commit();   // pdo object 4

PDO 对象 4 没有正在进行的事务!异常是正常的。

快速解决 :

在你尝试阻止

 $pdo = $this->connect();
 $pdo->beginTransaction();
  ....  // replace all $this->connect() by $pdo
 $pdo->commit();

推荐阅读