首页 / PHP 入门教程 / MySQL 事务处理

PHP 入门教程

MySQL 事务处理

本教程共 65 篇 · 第 56 篇 · 更新于 2026-07-24 · 约 7 分钟阅读

PHPPHP8MySQL事务ACIDCOMMITROLLBACKPDO

56. MySQL 事务处理

本节目标:理解事务的 ACID 特性,掌握 BEGINCOMMITROLLBACK 的用法,能够在 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;
Note

MySQL 的 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 官方文档,改写后所得。