PHP PDO没有活动事务
我尝试使用PDO类运行一个查询,并得到以下错误消息:尝试提交时没有活动事务 这是我的密码:PHP PDO没有活动事务,php,mysql,sql,pdo,sqltransaction,Php,Mysql,Sql,Pdo,Sqltransaction,我尝试使用PDO类运行一个查询,并得到以下错误消息:尝试提交时没有活动事务 这是我的密码: public function runExQuery($sql) { $preparedQuery = $this->connect()->prepare($sql); $this->connect()->beginTransaction(); $preparedQuery->execute(); $this
public function runExQuery($sql) {
$preparedQuery = $this->connect()->prepare($sql);
$this->connect()->beginTransaction();
$preparedQuery->execute();
$this->connect()->commit();
}
private function connect() {
return new PDO('mysql:host=' . $this->host . ';dbname=' . $this->database . '', $this->username, $this->password);
}
这个错误的原因是什么?我在以前的帖子中探讨过这类问题,但没有找到任何解决方案 您的::connect方法每次调用时都会创建一个新的PDO
由于事务在连接之外无法生存,因此重新连接会将其清除
要更正此问题,请将PDO对象存储为类属性:
class MyPdoClass
{
private $pdo;
// ...
public function connect()
{
if ($this->pdo instanceof PDO) {
return;
}
$this->pdo = new PDO(// ....
}
然后在调用connect后引用它:
//...
public function runExQuery($query)
{
$this->connect();
$this->pdo->prepare($query);
// ...
}
您的::connect方法每次调用时都会创建一个新的PDO
由于事务在连接之外无法生存,因此重新连接会将其清除
要更正此问题,请将PDO对象存储为类属性:
class MyPdoClass
{
private $pdo;
// ...
public function connect()
{
if ($this->pdo instanceof PDO) {
return;
}
$this->pdo = new PDO(// ....
}
然后在调用connect后引用它:
//...
public function runExQuery($query)
{
$this->connect();
$this->pdo->prepare($query);
// ...
}
每次调用$this->connect时,您都在创建一个新的PDO对象,因此如果您有:
$stmt1 = $this->connect()->prepare(" ... ");
$stmt2 = $this->connect()->prepare(" ... ");
$stmt1和$stmt2实际上是完全不同的PDO对象,因此,如果使用一个对象启动事务,它将不适用于另一个对象。相反,您应该保存一个PDO对象并引用它,而不是每次都创建一个新的PDO对象
大多数情况下,我发现只需将其传递给类的构造函数就更容易了,但是,如果您想进行最少的编辑,可以执行以下操作:
class YourClass {
private $dbh;
private function connect() {
if (!isset($this->dbh)) {
$this->dbh = new PDO('mysql:host=' . $this->host . ';dbname=' . $this->database, $this->username, $this->password);
}
return $this->dbh;
}
}
但是,您可能希望将名称更改为更符合逻辑的名称,如getDbh
如果您想将其放入对象的构造函数中,可以执行以下操作:
class YourClass {
private $dbh;
public function __construct(PDO $dbh) {
$this->dbh = $dbh;
}
}
$dbh = new PDO('mysql:host=' . $host . ';dbname=' . $database, $username, $password);
$yourclass = new YourClass($dbh);
然后在任何其他类方法中,您只需引用$this->dbh。以您的代码为例:
public function runExQuery($sql) {
$preparedQuery = $this->dbh->prepare($sql);
$this->dbh->beginTransaction();
$preparedQuery->execute();
$this->dbh->commit();
}
就我个人而言,这是我的做法。每次调用$this->connect时,您都在创建一个新的PDO对象,因此如果您有:
$stmt1 = $this->connect()->prepare(" ... ");
$stmt2 = $this->connect()->prepare(" ... ");
$stmt1和$stmt2实际上是完全不同的PDO对象,因此,如果使用一个对象启动事务,它将不适用于另一个对象。相反,您应该保存一个PDO对象并引用它,而不是每次都创建一个新的PDO对象
大多数情况下,我发现只需将其传递给类的构造函数就更容易了,但是,如果您想进行最少的编辑,可以执行以下操作:
class YourClass {
private $dbh;
private function connect() {
if (!isset($this->dbh)) {
$this->dbh = new PDO('mysql:host=' . $this->host . ';dbname=' . $this->database, $this->username, $this->password);
}
return $this->dbh;
}
}
但是,您可能希望将名称更改为更符合逻辑的名称,如getDbh
如果您想将其放入对象的构造函数中,可以执行以下操作:
class YourClass {
private $dbh;
public function __construct(PDO $dbh) {
$this->dbh = $dbh;
}
}
$dbh = new PDO('mysql:host=' . $host . ';dbname=' . $database, $username, $password);
$yourclass = new YourClass($dbh);
然后在任何其他类方法中,您只需引用$this->dbh。以您的代码为例:
public function runExQuery($sql) {
$preparedQuery = $this->dbh->prepare($sql);
$this->dbh->beginTransaction();
$preparedQuery->execute();
$this->dbh->commit();
}
就我个人而言,这就是我的做法。每次调用$this->connect时,它是否会创建一个新的PDO对象?如果是这样,您需要重用相同的对象。我的connect方法发布在那里$this->connect是否每次调用时都创建一个新的PDO对象?如果是这样,你需要重复使用同一个对象。我的连接方法发布之后,你发布了连接方法的内容,我添加了一些细节;看看这是否有助于解决问题;看看这是否有助于解决问题。