Laravel 提供四种数据库事务回滚方法:一、DB::transaction() 自动回滚;二、手动 beginTransaction/commit/rollback;三、savepoint 局部回滚;四、migrate:rollback 等命令回滚结构变更。

如果您在 Laravel 应用中执行多条数据库操作,但其中某一步失败导致数据不一致,则必须确保已执行的操作能全部撤销。以下是实现数据库事务回滚的多种方法:
一、使用 DB::transaction() 闭包自动回滚
该方式由 Laravel 内置支持,事务逻辑封装在匿名函数中;框架自动在异常未被捕获时执行 ROLLBACK,并重新抛出异常,适用于大多数原子性写入场景。
1、在控制器或服务类中引入 DB 门面:use Illuminate\Support\Facades\DB;
2、调用 DB::transaction() 并传入闭包:DB::transaction(function () { ... });
3、在闭包内执行全部数据库操作,例如创建用户并关联配置:User::create([...]); Config::create([...]);
4、若任意操作失败(如模型验证失败、QueryException 抛出),且异常未被 try/catch 捕获,事务将自动终止并回滚。
5、确保数据库连接已启用异常模式:'options' => [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION],否则 SQL 错误可能静默忽略。
二、手动调用 beginTransaction/commit/rollback
此方式将事务控制权完全交予开发者,适合需在回滚前后执行日志记录、通知或条件判断等扩展逻辑的场景。
1、显式开启事务:DB::beginTransaction();
2、将所有写入操作置于 try 块中:try { ... }
3、在 try 块末尾提交事务:DB::commit();
4、在 catch 块中先执行回滚:DB::rollback();
5、随后记录错误或重新抛出原始异常:throw $e;
三、使用 savepoint 实现局部回滚
当需要在大事务中对某段子逻辑独立控制回滚点(而非整个事务),可借助底层 savepoint 机制,避免因局部失败导致全局重试。
1、在事务开启后创建命名保存点:DB::statement('SAVEPOINT sp_order_process');
2、执行可能失败的子操作,例如库存扣减与物流单生成。
3、若子逻辑失败,回滚至该保存点:DB::statement('ROLLBACK TO SAVEPOINT sp_order_process');
4、继续执行后续操作,如更新订单状态为“待补货”。
5、最终根据整体结果决定调用 DB::commit() 或 DB::rollback()。
四、通过迁移命令回滚数据库结构变更
该方法作用于数据库 schema 层,用于撤销已执行的迁移文件,不涉及运行时数据操作,适用于开发与测试环境结构调整。
1、回滚最近一次迁移批次:php artisan migrate:rollback
2、回滚指定数量的迁移批次,例如两批:php artisan migrate:rollback --step=2
3、清空全部迁移记录并还原数据库至初始状态:php artisan migrate:reset
4、重置后立即重新执行所有迁移:php artisan migrate:refresh
5、仅刷新并填充测试数据:php artisan migrate:refresh --seed











