【问题标题】:Laravel Transactions Not working when this condition happenes发生这种情况时,Laravel 事务不起作用
【发布时间】:2021-01-01 23:25:07
【问题描述】:

让我从我的代码开始

在我的控制器文件中,这是代码

namespace Something\Somewhere\Controller{
class Mobile extends Controller{
    public function saveMobilesIntoDb(Request $request,MediaManager $manager){
        $requestMobileData = $request->all();
        DB::beginTransaction();
        try{
            /*Do something*/
            ..
            ..
            $bigMediaArray = $manager->mobileImagesManager($media,$insertedMobile,$mediaSlug);
            ..
            ..
            DB::commit();
        }catch (\Exception $exception) {
            DB::rollback();
            dump($exception);
        }
    }
}

}

请注意,我在那里使用了一项服务,该服务只不过是一个命名空间来管理服务类中的代码,这是发生了什么

namespace Something\Somewhere\Service{

class MediaManager{

    public function mobileImagesManager($media, $mobileId, $slug){
        //Do some stuff
        ///Create folder
        return array;
    }
}

现在的问题是当我在服务中遇到一些错误并且我重新发送数据然后假设插入数据库的最后一个 id 是 5 然后错误来了但没有回滚所以它用 7 保存了新的 id。我不希望这种情况发生。我知道当我不在范围内时回滚不起作用,但到目前为止我尝试的是

我将服务函数包装到 try-catch 中,并且在 catch 中我使用了 DB::rollback() 但它没有帮助。

请告诉我如何解决它并在我不在范围内时回滚所有内容。

感谢您的宝贵时间

【问题讨论】:

  • 你的意思是在服务功能中?不,我没有在那个函数中使用 beginTransaction
  • 根据您使用的数据库,回滚可能无法撤消自动增量 ID 的推进,从而在您的序列中留下一个“漏洞”。看来这就是您所描述的,应该不是问题。
  • @anasomush 是的,我正在使用 DB::beginTransaction();正如您在代码中看到的那样,位于最顶部。
  • @AlexHowansky 我使用的是 Mysql,表是 InnoDB,Innodb 支持事务。据我所知
  • 是的,但是自动增量 id 的递增不是该事务的一部分,因此如果您回滚,则会丢失一个 id。您可能会发现您的数据实际上已回滚,只是您的 id 序列中有一个漏洞。

标签: php laravel try-catch


【解决方案1】:

正如Alex所说,由于Mysql官方文档,事务失败后自动递增的ID不会回滚。

在所有锁定模式(0、1 和 2)中,如果 产生的交易 自动增量值回滚, 这些自动增量值是 “丢失的。”一旦为 一个自增列,它不能是 回滚,无论是否 “INSERT-like”语句完成, 以及是否包含 事务被回滚。如此失落 值不被重用。因此,可能有 是存储在一个值的差距 表的 AUTO_INCREMENT 列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-24
    • 2012-03-22
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多