导读:本期聚焦于小伙伴创作的《PHP如何实现数据库事务处理?PDO与mysqli实战教程》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《PHP如何实现数据库事务处理?PDO与mysqli实战教程》有用,将其分享出去将是对创作者最好的鼓励。

PHP数据库事务怎么处理_PHP事务处理方法与使用实例

在实际的PHP项目开发中,我们经常需要同时执行多个数据库操作,比如转账场景中,要同时从转出账户扣钱,再向转入账户加钱。如果这两个操作中间出现意外,就可能导致数据不一致,这时候就需要用到数据库事务来保证操作的原子性。下面我们就来详细讲解PHP中事务的处理方法,并结合实例说明具体用法。

什么是数据库事务

数据库事务是一组数据库操作的集合,这些操作要么全部执行成功,要么全部不执行,不会出现部分执行的情况。事务具备四个核心特性,也就是常说的ACID:

  • 原子性(Atomicity):事务中的所有操作是一个不可分割的整体,要么全部完成,要么全部回滚,不会停留在中间状态。
  • 一致性(Consistency):事务执行前后,数据库的状态都要符合预设的规则,比如转账前后两个账户的总金额保持不变。
  • 隔离性(Isolation):多个事务同时执行时,彼此之间不会互相干扰,每个事务都感觉不到其他事务的存在。
  • 持久性(Durability):事务一旦提交成功,对数据库的修改就是永久性的,即使数据库出现故障也不会丢失。

PHP中事务处理的基本流程

在PHP中操作MySQL数据库时,我们可以通过PDO或者mysqli扩展来处理事务,两者的核心流程一致,都遵循以下步骤:

  1. 关闭数据库的自动提交模式,因为默认情况下MySQL执行每条SQL都会自动提交,我们需要手动控制提交时机。
  2. 开启事务,标记接下来的一组操作属于同一个事务。
  3. 依次执行事务中的多个数据库操作。
  4. 检查所有操作是否都执行成功:如果全部成功,就手动提交事务,让修改生效;如果有任意一个操作失败,就回滚事务,撤销所有已经执行的操作。
  5. 恢复数据库的自动提交模式(可选,根据业务场景决定)。

使用PDO处理事务的实例

PDO是PHP中常用的数据库扩展,支持多种数据库,下面以MySQL为例,演示转账场景的事务处理:

<?php
// 数据库配置
$host = '127.0.0.1';
$dbname = 'test_db';
$username = 'root';
$password = '123456';

try {
    // 创建PDO连接,设置错误模式为异常,关闭自动提交
    $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 0);

    // 开启事务
    $pdo->beginTransaction();
    echo "事务已开启<br/>";

    // 转出账户扣钱:假设用户A的id是1,要转出500元
    $sql1 = "UPDATE user_account SET balance = balance - 500 WHERE id = 1 AND balance >= 500";
    $res1 = $pdo->exec($sql1);
    if ($res1 === false) {
        throw new Exception("转出账户扣钱失败");
    }

    // 转入账户加钱:假设用户B的id是2,转入500元
    $sql2 = "UPDATE user_account SET balance = balance + 500 WHERE id = 2";
    $res2 = $pdo->exec($sql2);
    if ($res2 === false) {
        throw new Exception("转入账户加钱失败");
    }

    // 所有操作成功,提交事务
    $pdo->commit();
    echo "转账成功,事务已提交<br/>";

} catch (Exception $e) {
    // 出现异常,回滚事务
    if (isset($pdo) && $pdo->inTransaction()) {
        $pdo->rollBack();
        echo "操作失败,事务已回滚,错误信息:" . $e->getMessage() . "<br/>";
    }
} finally {
    // 恢复自动提交模式
    if (isset($pdo)) {
        $pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 1);
        $pdo = null;
    }
}
?>

上面的代码中,我们首先关闭了自动提交,然后开启事务,接着执行两个更新操作。如果两个操作都成功,就提交事务;如果任意一个操作失败,就会抛出异常,进入catch块回滚事务,保证数据不会出现不一致的情况。最后在finally块中恢复自动提交并释放连接。

使用mysqli处理事务的实例

如果使用mysqli扩展,事务处理的逻辑和PDO类似,下面是同样的转账场景的mysqli实现:

<?php
// 数据库配置
$host = '127.0.0.1';
$username = 'root';
$password = '123456';
$dbname = 'test_db';

// 创建mysqli连接
$mysqli = new mysqli($host, $username, $password, $dbname);
if ($mysqli->connect_error) {
    die("连接失败:" . $mysqli->connect_error);
}
// 设置字符集
$mysqli->set_charset("utf8");

// 关闭自动提交,开启事务
$mysqli->autocommit(false);
echo "事务已开启<br/>";

try {
    // 转出账户扣钱
    $sql1 = "UPDATE user_account SET balance = balance - 500 WHERE id = 1 AND balance >= 500";
    $res1 = $mysqli->query($sql1);
    if (!$res1 || $mysqli->affected_rows == 0) {
        throw new Exception("转出账户扣钱失败");
    }

    // 转入账户加钱
    $sql2 = "UPDATE user_account SET balance = balance + 500 WHERE id = 2";
    $res2 = $mysqli->query($sql2);
    if (!$res2) {
        throw new Exception("转入账户加钱失败");
    }

    // 所有操作成功,提交事务
    $mysqli->commit();
    echo "转账成功,事务已提交<br/>";

} catch (Exception $e) {
    // 出现异常,回滚事务
    $mysqli->rollback();
    echo "操作失败,事务已回滚,错误信息:" . $e->getMessage() . "<br/>";
} finally {
    // 恢复自动提交
    $mysqli->autocommit(true);
    $mysqli->close();
}
?>

mysqli的处理方式和PDO的核心区别是方法和属性名称不同,比如开启事务不需要显式调用beginTransaction,关闭自动提交后用autocommit(false)就相当于开启了事务,提交用commit,回滚用rollback,最后同样要恢复自动提交并关闭连接。

事务使用的注意事项

在使用PHP处理数据库事务时,有几个点需要特别注意:

  • 并不是所有的数据库引擎都支持事务,比如MySQL的MyISAM引擎就不支持事务,只有InnoDB等引擎支持,所以使用前要确认表的存储引擎。
  • 事务的范围不要太大,尽量只包含必要的操作,长时间未提交的事务会占用数据库资源,甚至导致锁表,影响其他操作。
  • 事务中尽量避免执行耗时操作,比如复杂的查询、外部接口调用等,这些操作会延长事务的执行时间,增加风险。
  • 如果事务中包含了DDL语句(比如CREATE、ALTER等),大部分数据库会自动提交当前事务,所以事务中尽量不要使用DDL语句。

PHP数据库事务PDO事务mysqli事务MySQL事务ACID特性

免责声明:已尽一切努力确保本网站所含信息的准确性。网站部分内容来源于网络或由用户自行发表,内容观点不代表本站立场。本站是个人网站免费分享,内容仅供个人学习、研究或参考使用,如内容中引用了第三方作品,其版权归原作者所有。若内容触犯了您的权益,请联系我们进行处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。前端、网络、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握网站开发与运维所需的核心技术栈。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端逻辑,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。