Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php PDO事务不捕获异常_Php_Mysql_Pdo - Fatal编程技术网

Php PDO事务不捕获异常

Php PDO事务不捕获异常,php,mysql,pdo,Php,Mysql,Pdo,我第一次尝试PDO事务。下面的代码不起作用。我们尝试插入的电子邮件地址有重复项,因此应该会失败。这确实给了我一个错误。但是第一个插入被插入到数据库中,它不会回滚。我知道回滚工作,因为如果我将PDO::rollback移动到Try{before commit,它会回滚。我认为问题在于它没有捕获错误,因此没有调用PDO::rollback。有什么想法吗 try { PDO::beginTransaction(); $sql = "INSERT INTO .`tblUsersIDvsAgen

我第一次尝试PDO事务。下面的代码不起作用。我们尝试插入的电子邮件地址有重复项,因此应该会失败。这确实给了我一个错误。但是第一个插入被插入到数据库中,它不会回滚。我知道回滚工作,因为如果我将PDO::rollback移动到Try{before commit,它会回滚。我认为问题在于它没有捕获错误,因此没有调用PDO::rollback。有什么想法吗

try {
    PDO::beginTransaction();

$sql = "INSERT INTO .`tblUsersIDvsAgencyID` (`id`, `agency_id`) VALUES (NULL, :agencyID)";
$STH = $this->prepare($sql); 
$STH->bindParam(':agencyID', $AgencyUser['agency_id']);
$STH->execute();
$userID = parent::lastInsertId();

$sql = "INSERT INTO `tblUsersEmailAddress` (`id`, `user_id`, `email_address`, `primary`, `created_ts`, `email_verified`) VALUES (NULL ,  :userID ,  :EmailAddress ,  '1', CURRENT_TIMESTAMP ,  '0' )";
$STH = $this->prepare($sql); 
$STH->bindParam(':userID', $userID);
$STH->bindParam(':EmailAddress', $email_address);
$STH->execute();
PDO::commit();
echo 'Data entered successfully<br />';
}
catch(PDOException $e)
{
/*** roll back the transaction if we fail ***/
PDO::rollBack();
echo "failed";
} 
试试看{
PDO::beginTransaction();
$sql=“插入到.`tbluserisdvsagencyid`(`id`,`agency_id`)值中(NULL,:agencyID)”;
$STH=$this->prepare($sql);
$STH->bindParam(':agencyID',$AgencyUser['agencyID']);
$STH->execute();
$userID=parent::lastInsertId();
$sql=“插入到`tbluserEmailAddress`(`id`、`user\u id`、`email\u address`、`primary`、`created\u ts`、`email\u verified`)值中(NULL、:userID、:EmailAddress、`1',当前时间戳、`0');
$STH=$this->prepare($sql);
$STH->bindParam(':userID',$userID);
$STH->bindParam(':EmailAddress',$email_address);
$STH->execute();
PDO::commit();
echo“数据输入成功
”; } 捕获(PDO$e) { /***如果我们失败,请回滚事务***/ PDO::rollBack(); echo“失败”; }
PDO::beginTransaction()不是一个静态方法。从您的问题来看,它看起来像是在扩展PDO类。我不会这样做,因为我怀疑您是否在向基类添加任何重要内容。相反,您应该将PDO连接设置为类属性

比如说

class ParentClass
{
    /**
     * @var PDO
     */
    protected $dbh;

    public function __construct(PDO $dbh)
    {
        $this->dbh = $dbh;

        // Make sure PDO is set to throw exceptions
        $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }
}

class ChildClass extends ParentClass
{
    public function insertStuff()
    {
        $this->dbh->beginTransaction();
        try {
            // do stuff

            $this->dbh->commit();
        } catch (PDOException $e) {
            $this->dbh->rollBack();
            throw $e;
        }
    }
}

PDO::beginTransaction()
不是一个静态方法。从您的问题来看,它看起来像是在扩展PDO类。我不会这样做,因为我怀疑您是否在向基类添加任何重要内容。相反,您应该将PDO连接设置为类属性

比如说

class ParentClass
{
    /**
     * @var PDO
     */
    protected $dbh;

    public function __construct(PDO $dbh)
    {
        $this->dbh = $dbh;

        // Make sure PDO is set to throw exceptions
        $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }
}

class ChildClass extends ParentClass
{
    public function insertStuff()
    {
        $this->dbh->beginTransaction();
        try {
            // do stuff

            $this->dbh->commit();
        } catch (PDOException $e) {
            $this->dbh->rollBack();
            throw $e;
        }
    }
}

我将首先引用以下文件:

注意:某些MySQL表类型(存储引擎)不支持事务。当使用不支持事务的表类型编写事务数据库代码时,MySQL将假装事务已成功启动。此外,发出的任何DDL查询都将隐式提交任何挂起的事务

您的问题可能是预期行为。此外:

  • beginTransaction
    不是静态的(我重复Phil的声明,您不应该扩展PDO)
  • 调用$pdo->setAttribute(pdo::ATTR_ERRMODE,pdo::ERRMODE_异常)
  • 您从不在语句中调用
    closeCursor
    (这通常会导致问题)。(Phil指出,在这种情况下,这并不是明确需要的,但仍然是最佳做法)
  • 使用
    bindParam
    不会给用户ID变量带来任何好处,因为您正在使用它(一个不可重复使用的本地定义变量)

  • 我将首先引用以下文件:

    注意:某些MySQL表类型(存储引擎)不支持事务。当使用不支持事务的表类型编写事务数据库代码时,MySQL将假装事务已成功启动。此外,发出的任何DDL查询都将隐式提交任何挂起的事务

    您的问题可能是预期行为。此外:

  • beginTransaction
    不是静态的(我重复Phil的声明,您不应该扩展PDO)
  • 调用$pdo->setAttribute(pdo::ATTR_ERRMODE,pdo::ERRMODE_异常)
  • 您从不在语句中调用
    closeCursor
    (这通常会导致问题)。(Phil指出,在这种情况下,这并不是明确需要的,但仍然是最佳做法)
  • 使用
    bindParam
    不会给用户ID变量带来任何好处,因为您正在使用它(一个不可重复使用的本地定义变量)

  • 为什么要静态调用事务方法,如:
    PDO::beginTransaction();
    ?应该非静态调用它们,如:
    $this->beginTransaction();
    。至少,我认为它需要一个特定的连接才能知道在哪里应用事务调用。为什么要静态调用事务方法,如:
    PDO::beginTransaction();
    ?应该非静态调用它们,如:
    $this->beginTransaction()
    。至少,我认为它需要一个特定的连接来知道在哪里应用事务调用。@Phil ya正在将这个类扩展到另一个父类,扩展到PDO。我这样做的原因是当我将一个函数从这个类调用到它的父类时,父类执行一些与DB相关的函数它将使用相同的连接。@fireeyedboy我还应该怎么做?我应该让这个类构造函数构建DBH连接吗?@MofCA我想你没有理解继承的概念。当你调用
    父::
    方法时,你没有调用另一个对象上的操作。它是同一个实例。我的评论仍然是hOwer,你最好不要延伸PDO@M.:您最好将PDO对象传递给消费对象的构造函数,如下所示:这样,您可以使用另一个PDO连接轻松创建消费对象的另一个实例。这称为松耦合()。它使您的代码保持灵活性,而不是通过硬编码将其绑定在一起(例如在构造函数中)@MofCA我已经更新了我的答案,更完整了implementation@Phil我正在将这个类扩展到另一个扩展到PDO的父类。我这样做的原因是,当我将一个函数从这个类调用到它的父类时,父类执行一些与DB相关的函数,它将使用相同的连接。@fireeyedboy how else我应该这样做吗?我应该让这个类构造函数构建DBH连接吗?@MofCA我认为你不理解继承的概念。当你调用
    parent::