我们都使用DB::transaction()
进行多个插入查询。在这样做的时候,try...catch
应该放在它里面还是 Package 它呢?如果出现错误,事务会自动失败,那么是否有必要包括try...catch
呢?
Package 事务的try...catch
示例:
// try...catch
try {
// Transaction
$exception = DB::transaction(function() {
// Do your SQL here
});
if(is_null($exception)) {
return true;
} else {
throw new Exception;
}
}
catch(Exception $e) {
return false;
}
相反,一个DB::transaction()
Package 了一个try...catch:
// Transaction
$exception = DB::transaction(function() {
// try...catch
try {
// Do your SQL here
}
catch(Exception $e) {
return $e;
}
});
return is_null($exception) ? true : false;
或者仅仅是一个没有try...catch的事务
// Transaction only
$exception = DB::transaction(function() {
// Do your SQL here
});
return is_null($exception) ? true : false;
7条答案
按热度按时间jjhzyzn01#
如果您需要通过代码手动“退出"事务(无论是通过异常还是简单地检查错误状态),您不应该使用
DB::transaction()
,而是将代码 Package 在DB::beginTransaction
和DB::commit
/DB::rollback()
中:见业务单据
nfs0ujit2#
如果使用PHP7,请在
catch
中使用Throwable来捕获用户异常和致命错误。例如:
如果您的代码必须与PHP5可划分,请使用
Exception
和Throwable
:eni9jsuy3#
你可以把事务 Package 在try..catch上,甚至反转它们,这是我在laravel 5中使用的示例代码,如果你深入研究
DB:transaction()
,就像你编写手动事务一样。拉腊维尔交易
因此,您可以这样编写代码,并处理异常,例如通过flash将消息返回到表单中或重定向到另一个页面。闭包中的REMEMBER return在transaction()中返回,因此,如果您返回
redirect()->back()
,它不会立即重定向,因为它返回的是处理事务的变量。打包事务处理
那么另一种方法是抛出布尔变量并在事务函数外处理重定向,或者如果需要检索事务失败的原因,则可以从
catch(Exception $e){...}
内的$e->getMessage()
获取jchrr9hc4#
我决定给予这个问题的答案,因为我认为可以使用比复杂的try-catch块更简单的语法来解决这个问题。Laravel文档在这个问题上非常简短。
除了使用try-catch,您还可以使用
DB::transaction(){...}
Package 器,如下所示:您应该看到,在此设置中,用户和日志记录不能彼此分离。
关于上述实现的一些注意事项:
return
是事务的任何内容,这样您就可以使用在其回调中返回的response()
作为控制器的响应。throw
一个异常(或者有一个嵌套函数自动抛出异常,就像Eloquent中的任何SQL异常一样)。id
、updated_at
、created_at
和任何其他字段在为$user
对象创建之后可用(至少在此事务的持续时间内)。事务将通过您拥有的任何创建逻辑运行。但是,当抛出SomeCustomException
时,整个记录将被丢弃。id
的自动递增列在失败的事务上也会递增。在Laravel 5.8上测试
hjzp0vay5#
我使用的是Laravel 8,您应该将事务 Package 在try-catch中,如下所示:
waxmsbnn6#
在laravel 8中,您可以在try-catch中使用DB::transaction。例如:
如果每一个查询在尝试时失败,则运行捕获块。
mzmfm0qo7#
第一:在Laravel中使用PostgreSQL数据库会使事情变得更加棘手。
如果您在事务错误后不回滚,则以后的每个查询都将抛出此错误 * 在失败的sql事务中:错误:当前事务被中止,命令被忽略,直到事务块 * 结束。因此,如果你不能在回滚之前将原始错误消息保存在表中。
第二:重视口才模型属性体系。
Eloquent模型在更新错误后会保留更改的属性,所以如果我们想在catch块中更新该模型,我们需要丢弃坏属性。这不是dbtransaction事务,所以rollback命令是无用的。