PHP 入门教程
MySQL 事务处理
本教程共 65 篇 · 第 56 篇 · 更新于 2026-07-24 · 约 7 分钟阅读
PHPPHP8MySQL事务ACIDCOMMITROLLBACKPDO
56. MySQL 事务处理
本节目标:理解事务的 ACID 特性,掌握
BEGIN、COMMIT、ROLLBACK的用法,能够在 PHP 中正确实现事务控制。
银行转账是最经典的事务场景:A 账户扣款和 B 账户收款必须同时成功或同时失败。事务就是保证这类”要么全做,要么全不做”的机制。
1. 什么是事务
事务(Transaction)是一组 SQL 操作的集合。事务结束时,所有操作要么全部提交(Commit),要么全部回滚(Rollback)。
ACID 特性
| 特性 | 说明 |
|---|---|
| Atomicity(原子性) | 事务是最小执行单位,不可再分 |
| Consistency(一致性) | 事务前后,数据保持完整约束 |
| Isolation(隔离性) | 多个事务互不干扰 |
| Durability(持久性) | 提交后数据永久保存 |
2. MySQL 事务基本语法
-- 开启事务
BEGIN;
-- 或 START TRANSACTION;
-- 执行操作
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
-- 提交事务(永久保存)
COMMIT;
-- 如果中途出错,回滚事务(撤销所有操作)
ROLLBACK;
NoteMySQL 的
InnoDB引擎支持事务,MyISAM不支持。确保表使用ENGINE=InnoDB。
3. PDO 事务示例
<?php
$pdo = new PDO('mysql:host=localhost;dbname=my_shop;charset=utf8mb4', 'root', '123456');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
// 1. 开启事务
$pdo->beginTransaction();
// 2. 执行多个操作
$stmt = $pdo->prepare("UPDATE accounts SET balance = balance - :amount WHERE id = :from");
$stmt->execute([':amount' => 100, ':from' => 1]);
$stmt = $pdo->prepare("UPDATE accounts SET balance = balance + :amount WHERE id = :to");
$stmt->execute([':amount' => 100, ':to' => 2]);
// 3. 提交事务
$pdo->commit();
echo '转账成功';
} catch (PDOException $e) {
// 4. 出错时回滚
$pdo->rollBack();
echo '转账失败:' . $e->getMessage();
}
4. 自动提交模式
MySQL 默认开启自动提交(autocommit),每条 SQL 自动成为一个事务。
<?php
// 关闭自动提交
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 0);
// 现在需要手动 beginTransaction / commit
Tip使用 PDO 的
beginTransaction()时,PDO 会自动关闭当前连接的自动提交,事务结束后恢复。
5. 保存点(Savepoint)
复杂事务中,可以设置保存点,回滚到指定位置而不是全部撤销。
<?php
$pdo->beginTransaction();
try {
$pdo->exec("INSERT INTO orders (user_id, total) VALUES (1, 200)");
$orderId = $pdo->lastInsertId();
// 设置保存点
$pdo->exec("SAVEPOINT after_order");
try {
$pdo->prepare("INSERT INTO order_items (order_id, product_id) VALUES (?, ?)")
->execute([$orderId, 5]);
} catch (PDOException $e) {
// 仅回滚到保存点,订单记录保留
$pdo->exec("ROLLBACK TO SAVEPOINT after_order");
}
$pdo->commit();
} catch (PDOException $e) {
$pdo->rollBack();
}
6. 事务使用场景
| 场景 | 说明 |
|---|---|
| 金融操作 | 转账、充值、退款 |
| 库存扣减 | 下单时减库存、加订单记录 |
| 批量导入 | 要么全部导入成功,要么全部不导入 |
| 数据迁移 | 多表关联更新保持一致 |
Note事务不是万能的。持有事务时间过长会锁定数据,影响并发性能。事务内的操作应尽量精简。
小结
事务是保证数据一致性的核心机制。beginTransaction()、commit()、rollBack() 三个方法配合使用,让复杂业务操作变得安全可靠。
来源:参考了 php-the-right-way、PHP 官方文档、MySQL 官方文档,改写后所得。