thinkphp8 中处理数据库事务的核心方法是调用 db::transaction(),它接受一个闭包函数作为参数。在闭包内部执行具体的增删改查操作,若代码正常执行完毕则自动提交事务;若在闭包内抛出异常或显式调用 rollback(),则自动回滚所有更改。

如何编写基于 Db::transaction 的事务代码
使用 Db::transaction() 时,必须传入一个匿名函数(Closure)。该函数接收一个 $db 实例作为参数,所有的数据库操作都应在这个闭包内进行。如果闭包内的逻辑全部成功执行,框架会自动提交事务;如果发生异常,框架会捕获异常并自动回滚。

use think\facade\Db;
try {
$result = Db::transaction(function ($db) {
// 模拟业务逻辑:转账
$db->table('user')
->where('id', 1)
->dec('balance', 100)
->update();
$db->table('user')
->where('id', 2)
->inc('balance', 100)
->update();
return true; // 返回任意值均可,只要不抛异常
});
echo '事务提交成功';
} catch (\Exception $e) {
echo '事务回滚: ' . $e->getMessage();
}
手动控制事务提交与回滚的场景
虽然推荐使用闭包方式让框架自动管理事务边界,但在某些复杂场景下,你可能需要更精细的控制,例如在事务中间进行条件判断后决定是继续还是回滚。此时可以脱离 Db::transaction() 的自动管理模式,直接使用 startTrans()、commit() 和 rollback() 方法。
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。

use think\facade\Db;
try {
Db::startTrans();
$res1 = Db::table('order')->insert(['user_id' => 1, 'amount' => 50]);
if (!$res1) {
throw new \Exception('订单创建失败');
}
$res2 = Db::table('inventory')->where('id', 10)->dec('stock', 1)->update();
if ($res2 === false) {
throw new \Exception('库存扣减失败');
}
Db::commit();
echo '手动事务提交成功';
} catch (\Exception $e) {
Db::rollback();
echo '手动事务回滚: ' . $e->getMessage();
}
事务中嵌套子事务会发生什么
在 ThinkPHP8 中,如果在已经开启的事务中再次调用 Db::transaction() 或 startTrans(),这被视为嵌套事务。由于 MySQL 的 InnoDB 引擎默认不支持真正的嵌套事务(Nested Transactions),ThinkPHP 会通过保存点(Savepoint)机制来模拟。外层事务提交时,所有保存点才会真正生效;如果内层“事务”失败并触发回滚,它只会回滚到当前的保存点,而不会影响外层事务的其他部分,除非外层也一并回滚。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










