
PHP 中使用 PDO 进行事务控制,核心是关闭自动提交(autocommit),手动调用 beginTransaction()、commit() 和 rollback(),并配合异常处理确保数据一致性。
开启事务前的必要准备
确保 PDO 实例已启用异常模式,否则事务失败时不会抛出异常,rollback() 容易被跳过:
- 创建 PDO 连接时设置
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION - 确认数据库引擎支持事务(如 MySQL 的 InnoDB,MyISAM 不支持)
- 避免在事务中执行无法回滚的操作(如 DDL 语句
CREATE TABLE、DROP,或文件写入、HTTP 请求等)
标准事务执行流程(推荐写法)
将业务逻辑包裹在 try...catch 中,成功则 commit(),出错则 rollback():
$pdo = new PDO($dsn, $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
<p>try {
$pdo->beginTransaction();</p><pre class="brush:php;toolbar:false;">// 示例:转账操作(A 减款,B 加款)
$pdo->exec("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
$pdo->exec("UPDATE accounts SET balance = balance + 100 WHERE id = 2");
// 可选:检查业务规则(如余额是否足够)
$stmt = $pdo->query("SELECT balance FROM accounts WHERE id = 1");
if ($stmt->fetchColumn() < 0) {
throw new Exception("余额不足,事务终止");
}
$pdo->commit();
echo "事务执行成功";} catch (Exception $e) { $pdo->rollback(); echo "事务已回滚:" . $e->getMessage(); }
嵌套事务与保存点(Savepoint)
PDO 本身不支持真正嵌套事务,但可通过 SAVEPOINT 模拟局部回滚:
立即学习“PHP免费学习笔记(深入)”;
- 使用
$pdo->exec("SAVEPOINT sp1")设置保存点 - 出错时执行
$pdo->exec("ROLLBACK TO SAVEPOINT sp1")回退到该点,不影响外层事务 - 最终仍需统一
commit()或外层rollback() - 注意:不同数据库对保存点语法和行为略有差异(MySQL/PostgreSQL 支持良好,SQLite 需开启 WAL 模式)
事务中的查询与预处理注意事项
事务内执行查询或更新时,建议统一使用预处理语句提升安全性和性能:
- 所有
INSERT/UPDATE/DELETE推荐用prepare()+execute(),防止 SQL 注入 - 事务期间的
SELECT默认使用当前事务的隔离级别(如可重复读),结果反映事务内已修改但未提交的数据 - 避免在事务中调用
lastInsertId()后再执行可能失败的操作——ID 已生成,但事务若回滚,ID 不会回退(自增主键特性)











