php数据库事务核心是确保操作全成功或全回滚,推荐用pdo(跨库、异常友好)或mysqli(仅mysql),需innodb引擎,避免隐式提交与耗时操作,配合try-catch实现闭环控制。

PHP 中使用数据库事务,核心是确保一组操作要么全部成功、要么全部回滚,避免数据不一致。最常用且推荐的方式是通过 PDO(支持多种数据库)或 mysqli(仅 MySQL)开启事务,并配合 beginTransaction()、commit() 和 rollback() 控制流程。
使用 PDO 实现事务控制(推荐)
PDO 支持跨数据库,自动关闭自动提交模式,语法清晰,异常处理友好。
- 创建 PDO 实例时需关闭自动提交(默认已关,但显式设置更安全):
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, false); - 调用
$pdo->beginTransaction()显式开启事务 - 执行多条 SQL(如 INSERT/UPDATE/delete),任一失败则手动
rollback() - 全部成功后调用
$pdo->commit() - 建议用 try-catch 包裹,捕获异常后自动回滚
示例代码:
try { $pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->beginTransaction(); <pre class='brush:php;toolbar:false;'>$pdo->exec("INSERT INTO accounts (name, balance) VALUES ('Alice', 1000)"); $pdo->exec("UPDATE accounts SET balance = balance - 200 WHERE name = 'Alice'"); $pdo->exec("UPDATE accounts SET balance = balance + 200 WHERE name = 'Bob'"); $pdo->commit(); echo "转账成功";
} catch (PDOException $e) { $pdo->rollback(); echo “操作失败:” . $e->getMessage(); }
使用 MySQLi 实现事务控制
MySQLi 面向对象风格同样支持事务,适用于纯 MySQL 环境。注意必须使用 mysqli_real_connect() 或构造函数连接,并确认引擎为 InnoDB(MyISAM 不支持事务)。
立即学习“PHP免费学习笔记(深入)”;
- 调用
$mysqli->begin_transaction()开启事务(MySQLi 8.0+ 推荐)或$mysqli->autocommit(false) - 执行 SQL 后检查每步是否成功(
$mysqli->affected_rows > 0或用errno判断) - 出错时调用
$mysqli->rollback(),成功后$mysqli->commit()
示例代码:
$mysqli = new mysqli('localhost', 'user', 'pass', 'test'); $mysqli->begin_transaction(); <p>if (!$mysqli->query("INSERT INTO logs (msg) VALUES ('start')") || !$mysqli->query("UPDATE users SET status = 'active' WHERE id = 123")) { $mysqli->rollback(); echo "事务回滚:" . $mysqli->error; } else { $mysqli->commit(); echo "事务提交成功"; }</p>
事务中的常见注意事项
事务不是万能的,实际使用中需避开几个典型陷阱:
- 只对支持事务的存储引擎生效:MySQL 中必须用 InnoDB;MyISAM 或 Memory 引擎下
START TRANSACTION无实际作用 - 避免在事务中做耗时操作:如发送邮件、调用外部 API、大文件读写——会延长锁持有时间,影响并发性能
- DML 以外的语句可能隐式提交:如
CREATE table、DROP TABLE、ALTER TABLE在 MySQL 中会自动触发COMMIT,导致事务中断 - 连接生命周期内事务独立:每个数据库连接有自己事务上下文,不能跨连接共享或传播(分布式事务需额外方案如 XA 或业务层补偿)
简单封装一个事务助手类(可选增强)
为减少重复 try-catch,可封装一个轻量工具方法:
function transactional(callable $callback, PDO $pdo) { $pdo->beginTransaction(); try { $result = $callback($pdo); $pdo->commit(); return $result; } catch (Exception $e) { $pdo->rollback(); throw $e; } } <p>// 使用 transactional(function ($pdo) { $pdo->exec("INSERT INTO orders (...) VALUES (...)"); $pdo->exec("UPDATE inventory SET qty = qty - 1 WHERE id = 1"); }, $pdo);</p>
事务控制本质是数据一致性的守门人。只要确保开启、检查、提交/回滚三步闭环,再避开引擎和语句限制,就能稳定落地。