php事务开始语句

admin 106 0
PHP事务开始语句主要用于确保数据库操作的原子性,通过mysqli_begin_transaction($link)或PDO的$pdo->beginTransaction()启动事务,事务执行过程中,多个SQL语句被视作单一单元,若中途失败可通过mysqli_rollback()$pdo->rollBack()回滚,全部成功则用mysqli_commit()$pdo->commit()提交,避免数据不一致,常用于涉及多表操作的场景,如转账、订单创建等,需配合错误处理机制确保数据安全。

PHP事务开始语句详解:从基础到实践

在数据库操作中,事务是保证数据一致性和完整性的核心机制,无论是金融转账、订单扣库存还是用户注册时的多表联动,都需要通过事务来确保一系列操作要么全部成功,要么全部失败,而在PHP中,事务的开始语句是控制这一流程的"起点",正确使用它对构建健壮的数据库应用至关重要,本文将从基础概念出发,结合PHP中主流数据库扩展(MySQLi/PDO)的用法,详细解析事务开始语句的使用方法、注意事项及最佳实践。

事务的核心概念:为什么需要事务?

在深入PHP事务开始语句之前,我们先明确事务(Transaction)的定义和核心特性,事务是数据库操作的最小执行单元,一组操作要么全部提交(Commit)生效,要么全部回滚(Rollback)撤销,不可分割,其核心特性可通过ACID原则(原子性Atomicity、一致性Consistency、隔离性Isolation、持久性Durability)概括:

  • 原子性(Atomicity):事务内的操作不可分割,要么全部完成,要么全部不执行。
  • 一致性(Consistency):事务执行前后,数据库状态必须一致(如转账总金额不变)。
  • 隔离性(Isolation):并发事务之间互不干扰,一个事务的中间结果对其他事务不可见。
  • 持久性(Durability):事务提交后,对数据库的修改永久保存,即使系统崩溃也不会丢失。

以电商下单场景为例,需要同时执行"扣减库存"、"创建订单"、"增加用户积分"三个操作,若其中一个失败(如库存不足),则所有操作需回滚,避免数据不一致,事务就是保证这一逻辑的关键,而事务的开始语句则是触发事务机制的"开关"。

PHP中的事务开始语句:MySQLi与PDO的写法

PHP操作数据库的主流扩展包括MySQLi(面向过程/面向对象)和PDO(PHP Data Objects,支持多种数据库),两者的事务开始语句略有不同,但核心逻辑一致:显式开启事务,关闭自动提交模式

MySQLi中的事务开始语句

MySQLi提供了两种方式开启事务:

  1. 面向对象风格mysqli::begin_transaction()(PHP 5.6.0+ 推荐,语义更清晰)
  2. 面向过程风格mysqli_autocommit($link, FALSE)(关闭自动提交,隐式开启事务)
示例:面向对象风格开启事务
$mysqli = new mysqli("localhost", "root", "password", "test_db");
if ($mysqli->connect_errno) {
    die("连接失败: " . $mysqli->connect_error);
}
// 开启事务(推荐方式)
$mysqli->begin_transaction();
try {
    // 执行SQL操作1:扣减库存
    $result = $mysqli->query("UPDATE products SET stock = stock - 1 WHERE id = 1");
    if (!$result) {
        throw new Exception("库存更新失败");
    }
    // 执行SQL操作2:创建订单
    $result = $mysqli->query("INSERT INTO orders (product_id, user_id, status) VALUES (1, 100, 'pending')");
    if (!$result) {
        throw new Exception("订单创建失败");
    }
    // 提交事务
    $mysqli->commit();
    echo "事务提交成功,操作完成!";
} catch (Exception $e) {
    // 发生异常,回滚事务
    $mysqli->rollback();
    echo "事务回滚: " . $e->getMessage();
}
$mysqli->close();
示例:面向过程风格开启事务
$link = mysqli_connect("localhost", "root", "password", "test_db");
if (!$link) {
    die("连接失败: " . mysqli_connect_error());
}
// 关闭自动提交(隐式开启事务)
mysqli_autocommit($link, FALSE);
try {
    mysqli_query($link, "UPDATE products SET stock = stock - 1 WHERE id = 1");
    mysqli_query($link, "INSERT INTO orders (product_id, user_id, status) VALUES (1, 100, 'pending')");
    // 提交事务
    mysqli_commit($link);
    echo "事务提交成功!";
} catch (Exception $e) {
    mysqli_rollback($link);
    echo "事务回滚: " . $e->getMessage();
}
mysqli_close($link);

关键点

  • begin_transaction()是PHP 5.6.0后引入的显式方法,比autocommit更直观,推荐使用。
  • 开启事务后,需手动调用commit()提交或rollback()回滚。
  • 在事务执行过程中,任何一条SQL语句失败都应触发异常并回滚。
  • MySQLi默认的隔离级别是REPEATABLE READ,可通过mysqli::query("SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED");修改。

PDO中的事务开始语句

PDO提供了更简洁的事务控制方式,主要使用beginTransaction()方法:

try {
    $pdo = new PDO("mysql:host=localhost;dbname=test_db", "root", "password");
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    // 开启事务
    $pdo->beginTransaction();
    // 执行SQL操作1:扣减库存
    $stmt = $pdo->prepare("UPDATE products SET stock = stock - 1 WHERE id = :id");
    $stmt->execute(['id' => 1]);
    // 执行SQL操作2:创建订单
    $stmt = $pdo->prepare("INSERT INTO orders (product_id, user_id, status) VALUES (:product_id, :user_id, :status)");
    $stmt->execute([
        'product_id' => 1,
        'user_id' => 100,
        'status' => 'pending'
    ]);
    // 提交事务
    $pdo->commit();
    echo "事务提交成功!";
} catch (Exception $e) {
    // 发生异常,回滚事务
    if (isset($pdo) && $pdo->inTransaction()) {
        $pdo->rollback();
    }
    echo "事务回滚: " . $e->getMessage();
}

PDO事务特点

  • PDO支持多种数据库(MySQL、PostgreSQL、SQLite等),代码更具通用性。
  • 使用预处理语句(prepare/execute)可以防止SQL注入,提高安全性。
  • inTransaction()方法可以检查当前是否处于事务中。
  • PDO默认的自动提交模式为开启,必须显式调用beginTransaction()才能开启事务。

事务隔离级别与并发控制

事务的隔离级别决定了并发事务之间的相互影响程度,MySQL支持四种隔离级别:

**READ UNCOMMITTED

标签: #php #事务 #开始 #语句