首页 » 小蓝 » PHP pdo 事务,代码里的一个容易踩的坑

PHP pdo 事务,代码里的一个容易踩的坑

PHP pdo 在支持事务的存储引擎(innoDB)下,可以使用以下代码实现事务

$pdo->beginTransaction();

try{
    $pdo->exec('insert into tt set s=11,t=99 ');
    $pdo->commit();
    // 注意!!
}catch (Exception $e){
    var_dump($e);
    $pdo->rollback();
}

上面的逻辑,在数据库插入失败时,会执行rollback,本次事务结束。

表面上看这段代码没有问题,

但是,如果你在上面【注意】的地方,还有其他代码的话。比如:

$pdo->beginTransaction();

try{
    $pdo->exec('insert into tt set s=11,t=99 ');
    $pdo->commit();
    // 注意!!
    throw new Exception('boom');
}catch (Exception $e){
    var_dump($e);
    $pdo->rollback();
}

这样一来,数据库插入没有问题,顺利commit ,但是catch到了一个其他的异常,

导致rollback也被执行了一次,这时候 pdo 会报一个错误

Uncaught PDOException: There is no active transaction in ...

这是因为 beginTransaction 会让这个事务状态为 active,

commitrollback 会让事务变成 inactive

显而易见,当然不能执行了 commit 后又执行 rollback 了。

所以, commit 应该写在 try 语句块的最后一行。