PDO如何完成事务操作

起因

无意间翻看极客学院的APP,准备找一些教程看看.看到一篇PDO 安全处理与事务处理,一想对MySQL的事务处理仅仅停留在概念上(知道执行多条语句,其中一个失败了,就会回滚操作)。但是把概念变成代码还真没实践过,于是就打开了。

视频讲解的还是比较基础详细的:

MySQL数据表应该为InnoDB类型

事务处理操作方法主要包括:

  1. beginTransaction() //开启一个事务

  2. commit() //事务提交

  3. rollBack() //事务回滚操作

PS:

PDO::ATTR_ERRMODE:错误报告

PDO::ERRMODE_SILENT: 仅设置错误代码

PDO::ERRMODE_WARNING: 引发 E_WARNING 错误

PDO::ERRMODE_EXCEPTION: 抛出 exceptions 异常

但是其中一段代码是有问题的,首先我看到的是roolback拼错了,然后仔细一看:先die掉,然后执行rollBack方法,肯定是有问题的啊。

但是实际执行过程中,因为对name字段有个唯一索引,事务并没有成功提交。而且rollBack方法也没有执行。但是数据却没有插入。本来想着一上午就搞定的问题,因为这个问题的出现,导致又花费几个小时解决。

问题

问题:Is it necessary to rollback if commit fails?

$mysqli->autocommit(false); //Start the transaction
$success = true;    

/* do a bunch of inserts here, which will be rolled back and
   set $success to false if they fail */

if ($success) {
    if ($mysqli->commit()) {
        /* display success message, possibly redirect to another page */
    }
    else {
        /* display error message */
        $mysqli->rollback(); //<----------- Do I need this?
    }
}

$mysqli->autocommit(true); //Turns autocommit back on (will be turned off again if needed)

//Keep running regardless, possibly executing more inserts

SF上也有相同的疑问~~~ 并且没人能解答。

解决

紧接着又找,看来也有人跟我相同的疑问,rollBack方法会自动执行?终于找到了答案!

If you don't commit not rollback an opened transaction, and it's not commited anywhere later in your script, it won't be commited (as seen by the database engine), and will automatically rolled-back at the end of your script.

上述引用大概的意思是:在开启一个事物没有执行commit方法或者rollBack方法,在脚本最后也不会执行commit方法并且在脚本最后将会执行rollBack方法。

参考中还提到方便别人理解,否则别人不知道是否需要回滚操作,还是之后写了。

The code is more easy to read / understand : when one sees $db->rollback(), he knows I want the transaction rolled-back for sure, and he doesn't have to think "did he really want to rollback, or did he forget something ? and what about later in the script ?"

注意

因此,设想唯一索引字段插入了一条相同的数据,导致程序进入捕捉了异常。此时没有写rollback执行回滚操作。而项目组其他人员不知道最终执行执行过rollback操作。大A写了一个rollback方法,经过大量代码,小d又写了一个rollback操作,从而又抛出可一个新的异常:"There is no active transaction",没开始一个激活的事务。

参考

http://www.jikexueyuan.com/course/653.html
http://stackoverflow.com/questions/38133260/is-it-necessary-to-rollback-if-commit-fails
http://stackoverflow.com/questions/2001698/if-an-php-pdo-transaction-fails-must-i-rollback-explicitely

转载于:https://www.cnblogs.com/luyuqiang/p/pdo-transaction.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是 PHP PDO 连接 MySQL 并支持事务逻辑、错误时打印 log 的示例代码: ```php // 数据库连接信息 $host = 'localhost'; $dbname = 'database_name'; $username = 'username'; $password = 'password'; // 创建 PDO 连接 try { $pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password); // 设置 PDO 错误模式为异常 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 开始事务 $pdo->beginTransaction(); // 执行 SQL 语句 $pdo->exec("INSERT INTO table_name (column1, column2, column3) VALUES ('value1', 'value2', 'value3')"); // 提交事务 $pdo->commit(); echo "数据插入成功!"; } catch(PDOException $e) { // 回滚事务 $pdo->rollback(); // 打印错误信息到日志文件 $error_message = $e->getMessage(); $log_file = 'pdo_error.log'; file_put_contents($log_file, date('Y-m-d H:i:s') . ' ' . $error_message . PHP_EOL, FILE_APPEND); echo "数据插入失败,请查看日志文件 $log_file 获取更多信息。"; } ``` 以上代码中,我们首先创建了 PDO 连接对象 `$pdo`,并设置其错误模式为异常。然后,我们使用 `$pdo->beginTransaction()` 开始事务,在事务中执行 SQL 语句,如有错误则使用 `$pdo->rollback()` 回滚事务。如果一切正常,则使用 `$pdo->commit()` 提交事务完成数据插入操作。 如果执行过程中出现错误,则会捕获 `PDOException` 异常,并将错误信息写入日志文件中,同时在页面上输出错误提示。 希望这个示例可以帮到您!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值