Laravel 事件如何知道事务回滚?Laravel 版本 < 8
Laravel 版本 >= 8 有专门的方法解决这个问题。
背景
如标题,我们使用 Eloquent 的事件的时候,能很轻松解耦业务逻辑,但现实生活中,总会出现:
如果 A 则 B,否则 回滚 B。
事务开始:
保存B // 触发 update 事件
if (A)
事务回滚
else
事务提交
在 Laravel 版本 < 8 的版本,可以发现,就算事务回滚,保存B 也会触发的 update 事件,那么,如何在事件的监听者中,知道事务提交 或者 回滚?
大家有解决方案吗?
在我们社区 和 网上找了一大圈,发现没有合适我当前版本Laravel的解决方案,但提供了一些思路。 最后通过一个比较绕的方法做了这件事。
实践代码
思路: 触发事件->事件观察者->队列
把原来 事件观察者 要做的事,移到队列。
演示代码[环境 Laravel 6]:
B Model:
// B Model 启用更新事件
protected $dispatchesEvents = [
'updated' => BUpdatedEvent::class
];
B Model Listeners:
// B Model Listeners:
public function handle(BUpdatedEvent $event)
{
// B model 当前的数据数组
$currentBModelArr = $event->BModel->toArray();
// 队列会每次重新获取model数据, 所以才把 操作前,后当前的实时数据给到队列
dispatch(new BUpdatedJob($event->BModel, $currentBModelArr));
}
BUpdatedJob:
public function __construct(BModel $bModel, array $currentBModelArr)
{
$this->currentBModelArr = $currentBModelArr;
$this->bModel = $bModel;
}
public function handle()
{
// 当前数据的最后更新时间 和 添加到队列时的不相等,说明对更新没有成功也就是事务未提交
// 如果成功的话,数据的时间应该是相等的。
// [也可以用其它字段判断]
if ($this->bModel->update_time != $this->currentBModelArr['update_time'])
return;
// 事务提交的处理逻辑
// some code.
}
总结
队列可以传递数据,
队列被消费的时候,会自动实例化 Model,
通过实例化 Model 的更新时间字段 与推送数据时 Model 的更新时间字段做 判断,
借此判断事务是否提交。
这个解决方案,纯属手里握着锤子,看全世界都是钉子,但,能用!
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: