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免费学习笔记(深入)”;
Difeye是一款超轻量级PHP框架,主要特点有: Difeye是一款超轻量级PHP框架,主要特点有: ◆数据库连接做自动主从读写分离配置,适合单机和分布式站点部署; ◆支持Smarty模板机制,可灵活配置第三方缓存组件; ◆完全分离页面和动作,仿C#页面加载自动执行Page_Load入口函数; ◆支持mysql,mongodb等第三方数据库模块,支持读写分离,分布式部署; ◆增加后台管理开发示例
- 调用
$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>事务控制本质是数据一致性的守门人。只要确保开启、检查、提交/回滚三步闭环,再避开引擎和语句限制,就能稳定落地。










