您好!欢迎访问家园网-www.jy.wang!

家园网

解析pdo事务的操作步骤

网络 作者:本站 点击:

一、示例:

<?php
// ===== 第1步:数据库连接 =====
$dsn = 'mysql:host=localhost;dbname=test;charset=utf8';
$user = 'db_user';
$pass = 'db_password';
try {
    // 创建PDO实例(启用异常模式)
    $pdo = new PDO($dsn, $user, $pass, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_AUTOCOMMIT => 0 // 重要!关闭自动提交
    ]);
    // ===== 第2步:开启事务 =====
    $pdo->beginTransaction();
    echo "<pre>[事务状态] 事务已开启,进入原子操作模式</pre>";
    // ===== 第3步:核心操作1 - 写入用户表 =====
    $stmt1 = $pdo->prepare("INSERT INTO users(username, password) VALUES(?, ?)");
    $stmt1->execute(['test_user', password_hash('123456', PASSWORD_DEFAULT)]);
    $user_id = $pdo->lastInsertId();
    echo "<pre>[操作1] 用户主表写入成功,ID: {$user_id}</pre>";
    // ===== 第4步:核心操作2 - 写入资料表 =====
    $stmt2 = $pdo->prepare("INSERT INTO profiles(user_id, email) VALUES(?, ?)");
    $stmt2->execute([$user_id, 'test@example.com']); // 假设此处邮件已存在会触发唯一索引冲突
    echo "<pre>[操作2] 用户资料表写入成功</pre>";
    // ===== 第5步:提交事务 =====
    $pdo->commit();
    echo "<pre>[事务状态] 事务已提交,数据永久生效</pre>";
} catch (PDOException $e) {
    // ===== 第6步:异常处理 =====
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
        echo "<pre>[事务状态] 事务已回滚,所有操作撤销</pre>";
    }
    echo "<pre>[错误报告] 注册失败: " . $e->getMessage() . "</pre>";
}
?>

二、解析

以下是针对PDO事务操作的逐行解析和标准化步骤总结:


一、逐行代码解析

  1. 数据库连接配置

$dsn = 'mysql:host=localhost;dbname=test;charset=utf8';
$user = 'db_user';
$pass = 'db_password';
    • 定义数据库连接参数(主机、库名、字符集)和认证信息。

  1. PDO实例化与配置

$pdo = new PDO($dsn, $user, $pass, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_AUTOCOMMIT => 0
]);
    • ERRMODE_EXCEPTION:启用异常模式(错误时抛出PDOException)。

    • AUTOCOMMIT=0:关闭自动提交(事务必需)。

    • 关键配置:

  1. 开启事务

$pdo->beginTransaction();
    • 调用后,所有后续SQL操作进入“待提交”状态,直到显式调用commit()rollBack()

  1. 执行核心操作1(用户表写入)

$stmt1 = $pdo->prepare("INSERT INTO users(username, password) VALUES(?, ?)");
$stmt1->execute(['test_user', password_hash('123456', PASSWORD_DEFAULT)]);
$user_id = $pdo->lastInsertId();
    • 使用预处理语句防止SQL注入,lastInsertId()获取新插入的用户ID。

  1. 执行核心操作2(资料表写入)

$stmt2 = $pdo->prepare("INSERT INTO profiles(user_id, email) VALUES(?, ?)");
$stmt2->execute([$user_id, 'test@example.com']);
    • 关联写入用户资料表,假设此处可能因唯一索引冲突抛出异常。

  1. 提交事务

$pdo->commit();
    • 若所有操作成功,提交事务使更改永久生效。

  1. 异常处理与回滚

if ($pdo->inTransaction()) {
    $pdo->rollBack();
}
    • 发生异常时,检查是否处于事务中并回滚,撤销所有未提交的操作。


二、PDO事务操作标准化步骤

步骤关键方法/操作说明
1. 连接数据库new PDO()关闭自动提交(AUTOCOMMIT=0),启用异常模式。
2. 开启事务beginTransaction()标记事务开始,后续操作进入原子执行模式。
3. 执行SQL操作prepare() + execute()所有操作暂存于事务缓冲区,未实际写入数据库。
4. 提交或回滚commit() / rollBack()全部成功则提交;任一失败则回滚。
5. 异常处理try-catch + inTransaction()确保异常时能正确回滚,避免部分提交。

三、事务特性体现

  1. 原子性(Atomicity)

    • 操作2失败时,操作1的插入也会被回滚,保证“全成功或全失败”。

  2. 一致性(Consistency)

    • 事务前后数据库约束(如外键、唯一索引)始终有效。

  3. 隔离性(Isolation)

    • 默认隔离级别下,其他会话看不到未提交的更改。

  4. 持久性(Durability)

    • commit()后数据永久生效(即使系统崩溃)。


四、注意事项

  • 自动提交‌:必须显式关闭(AUTOCOMMIT=0),否则每条SQL会立即生效。

  • 异常捕获‌:必须用try-catch捕获PDOException,否则回滚可能失效。

  • 连接持久化‌:避免在事务中使用持久连接(ATTR_PERSISTENT),可能导致状态残留。

通过以上步骤,可确保数据库操作的完整性和可靠性。


标签: