Php PDO事务不捕获异常
我第一次尝试PDO事务。下面的代码不起作用。我们尝试插入的电子邮件地址有重复项,因此应该会失败。这确实给了我一个错误。但是第一个插入被插入到数据库中,它不会回滚。我知道回滚工作,因为如果我将PDO::rollback移动到Try{before commit,它会回滚。我认为问题在于它没有捕获错误,因此没有调用PDO::rollback。有什么想法吗Php PDO事务不捕获异常,php,mysql,pdo,Php,Mysql,Pdo,我第一次尝试PDO事务。下面的代码不起作用。我们尝试插入的电子邮件地址有重复项,因此应该会失败。这确实给了我一个错误。但是第一个插入被插入到数据库中,它不会回滚。我知道回滚工作,因为如果我将PDO::rollback移动到Try{before commit,它会回滚。我认为问题在于它没有捕获错误,因此没有调用PDO::rollback。有什么想法吗 try { PDO::beginTransaction(); $sql = "INSERT INTO .`tblUsersIDvsAgen
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)closeCursor
(这通常会导致问题)。(Phil指出,在这种情况下,这并不是明确需要的,但仍然是最佳做法)bindParam
不会给用户ID变量带来任何好处,因为您正在使用它(一个不可重复使用的本地定义变量)我将首先引用以下文件: 注意:某些MySQL表类型(存储引擎)不支持事务。当使用不支持事务的表类型编写事务数据库代码时,MySQL将假装事务已成功启动。此外,发出的任何DDL查询都将隐式提交任何挂起的事务 您的问题可能是预期行为。此外:
beginTransaction
不是静态的(我重复Phil的声明,您不应该扩展PDO)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::