有一个事件有四个侦听器。侦听器正在执行一些财务任务,因此,如果其中一个任务失败,则所有以前的侦听器都必须回滚以验证整个系统的一致性。我该怎么做?
当任务在功能中时,我可以这样做:
f1();
function f1(){
try{
DB:BeginTransaction();
//do the tasks
DB::commit();
f2();
}catch(Throwable $t){
DB::rollback();
}
}
function f2(){
try{
DB:BeginTransaction();
//do the tasks
DB::commit();
f3();
}catch(Throwable $t){
DB::rollback();
throw $t;
}
}
function f3(){
try{
DB:BeginTransaction();
//do the tasks
DB::commit();
}catch(Throwable $t){
DB::rollback();
throw $t;
}
}
正如您所看到的,当一个函数(比如f3()
(遇到异常时,它会回滚并抛出新的异常。因此,函数f2()
中的调用行遇到异常,它也会回滚并再次抛出异常,它会导致函数f1()
中的调用线再次遇到异常并回滚。因此,catch中的throw
链验证了以前函数中的所有数据库插入都是回滚的。
但如果是听众,我不知道如何处理。
您为每个函数执行单独的事务,因此它们是独立的。f3()
无法回滚f1()
,因为您正在调用f2
和f3
之前提交它。
然而,你可以这样做:
DB::beginTransaction();
try {
f1();
f2();
f3();
DB::commit();
} catch (/* your exceptions here */) { // QueryException is a good one to catch
DB::rollBack();
} catch (Exception $e) { // add generic Exception for good measure
DB::rollBack();
}
其中f1
、f2
和f3
只是任务。
function f1() {
// f1 tasks
}
function f2() {
// f2 tasks
}
function f3() {
// f3 tasks
}
或者在一切完成后直接拨打commit
。
f2();
DB::commit();
...
f3();
DB::commit();
至于事件侦听器。。。我不确定,但也许在传递连接实例($connection = DB::getConnection();
nad然后使用它进行查询.$connection->query()->.....
(时将它们链接起来可以工作。
文档中有一些关于在事务中使用(排队的(侦听器的信息,这里是
https://laravel.com/docs/queues#jobs-和数据库事务