PHP PDO事务回滚不起作用

Posted

技术标签:

【中文标题】PHP PDO事务回滚不起作用【英文标题】:PHP PDO transaction rollBack doesn't work 【发布时间】:2015-07-14 21:35:23 【问题描述】:

一切都好吗 请任何人都可以帮助我 我正在尝试使用 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, $issueDates 和 $banks 是大小相同的数组 $lists 也是一个大小相同的二维数组

请帮我解释一下为什么这段代码不回滚

【问题讨论】:

回滚数据库事务,严格来说与PHP无关。 IE。它不会改变你的变量值。 只是猜测:尝试在 try catch 块之外启动事务... 不幸的是,@Jochen Schultz 如果我要插入四行并且在第三次插入时有一些异常,它会插入前两行并停止,但我想它应该回滚前两行行 【参考方案1】:

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

还要检查以确保抛出的异常是 PDOException,否则它将通过 try/catch 而不会发生回滚。

【讨论】:

我正在使用 InnoDB 表 无赖:-s 抛出的异常是什么样的?只需确保它以 PDOException 的形式触发,而不是其他任何东西,并被一些外部 try catch 捕获。 代替$e-&gt;getMessage();调用var_dump($e);并检查异常对象的类名。 我试图调用 var_dump($e) 但正如你所说的@Kevin Nagurski 但它没有捕获任何异常我不知道为什么 看起来抛出的不是PDOException。将catch (PDOException $e) 更改为catch (Exception $e) 并将var_dump 放置到位。因为catch 语句非常具体,如果不是PDOException,它将直接进入下一个catch。【参考方案2】:

我会说应该这样做:

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

$pdo->beginTransaction();

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


$pdo->commit();

【讨论】:

没有捕捉到任何异常,也没有回滚

以上是关于PHP PDO事务回滚不起作用的主要内容,如果未能解决你的问题,请参考以下文章

@Transactional注解事务不回滚不起作用无效

Spring启动集成测试回滚不起作用

Spring @Transactional注解不回滚不起作用无效

Mysqli回滚不起作用

使用 PDO 自动提交

Spring @Transactional 和回滚不起作用,弹簧集成测试