【问题标题】:Laravel 5.3 did not roll back if DB::transaction throws an error?如果 DB::transaction 抛出错误,Laravel 5.3 没有回滚?
【发布时间】:2017-05-25 20:37:19
【问题描述】:

我在进行多次查询时尝试进行数据库事务。

我也试图捕捉事务之外的异常,就像

DB::transaction(function() {
   try{
        //....db queries
   }catch(\Exception $e){
        Log::info($e);
   }
});

当这里抛出一些异常时,事务似乎没有回滚,数据库中的数据已经改变。

如果我在 catch 语句中手动执行DB::rollBack(),我的所有数据都会正常,

这让我想我是否必须手动执行DB::rollBack()

但我记得 Laravel 的文档说如果我使用DB::transaction 管理我的数据库查询,当抛出异常时,DB::rollBack() 将自动执行?

在 Laravel 5.3 中改变了吗?

【问题讨论】:

  • 还显示您的正确代码以使您的问题更清楚
  • @msonowal 我只想讨论 DB::transaction 的逻辑,而不是确切的代码。如果你知道 Laravel,就很容易理解我在说什么,所以我认为我不必输入这么多代码来明确我的观点。

标签: database laravel


【解决方案1】:

关注此link。你不应该使用DB::transaction(),而是将你的代码包装在DB::beginTransactionDB::commit/DB::rollback()

希望这对你有用!

【讨论】:

  • 那么我是否应该使用 DB::beginTransaction 而不是 DB::transaction?如果是,何时使用 DB::transaction?似乎 DB::transaction 是不必要的。
  • @AbelLee:如果您想手动开始事务并完全控制回滚和提交,您可以使用beginTransaction 方法,Docs
  • 我只是想捕获事务中的异常,同时执行事务的原始行为。并非所有交易都是绝对正确的。如果是这样,DB::transaction 并不比 DB::beginTransaction 好
【解决方案2】:

如果您有多个表条目并根据彼此更新。建议您应该使用事务

$var_name = DB::transaction(function () {
//    DB operations.....
});

$var_name 成功时返回 null

更多详情请参考文档https://laravel.com/docs/5.3/database

希望这对您有所帮助。 如有任何疑问,请询问

【讨论】:

  • 先谢谢了,我已经阅读了文档,但我认为文档不是那么详细。它只是告诉我如何使用 DB::transaction 并且 DB::rollBack() 将以正常的事务方式执行,但我确实尝试...手动捕获,他们从未提及。
  • 你可能会得到一个不同的错误,因为我自己正在处理数据库事务,我不需要 try catch..请检查一次
  • 一些正常情况只有500,我知道这一点。我只想知道当我在数据库查询之外包装“try...catch”时是否必须手动执行 DB::rollBack()。
  • 我得到错误的原因,因为我没有向mysql提交不可为空的列,如果我没有包装“try...catch”,它会告诉我当我处于调试模式时,前端出现 db 错误但 500 错误。
  • 我用的是Laravel 5.3,发现如果不手动回滚,mysql会出现一些奇怪的性能,我猜是不是事务的原因是多线程的?因为我发现如果我在事务中执行“try...catch”,那么无论是否有任何异常,所有查询都将被执行。 id 列有时会更新或删除一些条目,但如果我在事务中同时进行删除和创建查询,则会保存一个条目。
【解决方案3】:

如果你这样实现,它不会自动执行, 但是如果你像下面这样使用它作为闭包

DB::transaction(function () {
    //db queries
});

会自动回滚。

【讨论】:

  • 我已经尝试过,就像你发布的那样,我什至不知道 DB::rollBack() 是否被执行,如果发生一些异常,它只会抛出一个“500”错误代码DB::事务。所以我想包装一个“try...catch”来让异常舒服。如果我这样做,我发现我必须手动 DB::rollBack() :(
【解决方案4】:

事务和try/catch的正确方法是这样的:

try {
    DB::transaction(function(){
        //your query stuff here
    });

    DB::commit(); //transactions had no error
} catch (\Exception $e ) {
    //transactions had an error
    DB::rollback();

    //do something with $e->getMessage();
}

目的是在您的查询失败时为您提供更大的控制权。这样,您可以捕获异常并回滚事务。否则,您只需执行交易即可。

【讨论】:

    猜你喜欢
    • 2014-09-16
    • 1970-01-01
    • 1970-01-01
    • 2013-05-01
    • 2017-03-16
    • 2017-04-18
    • 2019-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多