PHP PDO事务的回滚不起作用

3

一切都好吗?
请问有人能帮我解决一个与PHP PDO事务相关的问题吗?我尝试使用PHP PDO事务,但遇到了一个问题,我无法处理。
当它捕获异常时,rollBack函数不起作用。
以下是连接代码:

$host   = 'localhost';
$user   = 'root';
$pass   = '';
$error  = '';
$dbname = 'tameras_finance';
// Set DSN
$dsn = 'mysql:host=' . $host . '; dbname=' . $dbname;
// Set options
$options = array(
    PDO::ATTR_PERSISTENT => true,
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
// Create a new PDO instanace
try {
    $dbh = new PDO($dsn, $user, $pass);
    $dbh->exec("set names utf8");
}
//Catch any errors
catch (PDOException $e) {
    echo $error = $e->getMessage();
}  

这里是代码:

try{
    $dbh->beginTransaction();
    $dbh->query('SET @newDebit = (SELECT max(`debtor_id`) + 1 AS maxDebit FROM `vocher`)');
    for($x = 0; $x < count($debits); $x++){
        $dbh->query('UPDATE `vocher` SET `debtor_id` = @newDebit, `status_id` = "4" WHERE `id` = '.$debits[$x]);
    }

    for($x = 0; $x < count($others); $x++){
        $columns = '`acc_id`, `value`, `date`, `desc`, `reject`, `vo_type_id`, `user`, `debtor_id`';
        $vals  = "'".$accs[$x]."','".$values[$x]."','".$dates[$x]."','".$descs[$x]."','1','1','".$user."', @newDebit";
        if($others[$x] == 'e'){
            $columns .= ', `cheque_no`, `available_date`, `issue_date`, `bank_id`';
            $vals  .= ", '".$sns[$x]."', '".$availdates[$x]."', '".$issueDates[$x]."', '".$banks[$x]."'";
        }
        $dbh->query("INSERT INTO creditor (".$columns.") VALUES (".$vals.")");
        if($lists[$x] != 'e'){
            $lastId = $dbh->lastInsertId();
            $q  = 'INSERT INTO `creditor_cc` (`creditor`, `cc`) VALUES ';
            for($y = 0; $y < count($lists[$x]); $y++){
                $dif = count($lists[$x]) - $y;
                $q .= '(';
                $q .= '"' . $lastId . '",';
                $q .= '"'.$lists[$x][$y].'"';
                $q .= ')';
                if($dif > 1){
                    $q .= ',';
                }
            }
            $dbh->query($q);
        }
    }
    $dbh->commit();
} catch(PDOException $e) {
    echo $error = $e->getMessage();
    $dbh->rollBack();
}

这段代码没有回滚操作

  • $sns、$others、$accs、$values、$dates、$descs、$availdates和$banks是大小相同的数组
  • $lists也是一个大小相同的二维数组

请帮我搞清楚为什么这个代码没有回滚


它会回滚数据库事务,与 PHP 没有严格的关联。也就是说,它不会改变您的变量值。 - Jonnix
只是猜测:尝试在try catch块之外启动事务... - Jochen Schultz
很遗憾,@Jochen Schultz,如果我要插入四行数据,但在第三次插入时出现了异常,它只会插入前两行并停止,但我想它应该回滚前两行。 - Mohamed Salah
2个回答

5

MySQL的默认表类型MyISAM不支持事务。你需要确保使用的是InnoDB表。

同时,要检查被抛出的异常是否为PDOException,否则它将跳过try/catch并未能触发回滚操作。


我正在使用InnoDB表。 - Mohamed Salah
糟糕 :-s 抛出的异常长什么样子?请确保它被作为 PDOException 触发,而不是其他什么异常,并被某个外部 try catch 捕获。 - Kevin Nagurski
看起来抛出的不是 PDOException。将 catch (PDOException $e) { 更改为 catch (Exception $e) { 并放置 var_dump。因为 catch 语句非常具体,如果不是 PDOException,它会掉到下一个 catch。 - Kevin Nagurski
它也没有捕获异常 :( - Mohamed Salah
`$dbh->beginTransaction(); try{ //same code } catch(Exception $e) { //echo $error = $e->getMessage(); var_dump($e); $dbh->rollBack(); }$dbh->commit();` - Mohamed Salah
显示剩余5条评论

-1

我认为应该这样做:

$pdo = new \PDO(/*...*/);

$pdo->beginTransaction();

try {
//...
} catch(\Exception $e) {
    $pdo->rollBack();
    throw $e;
}

$pdo->commit();

没有捕获任何异常,也没有回滚。 - Mohamed Salah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接