【发布时间】:2021-07-15 10:59:45
【问题描述】:
我有一个工匠命令,我正在清理一些已经变坏的数据。在我实际删除数据之前,我想进行一次试运行,并展示删除该数据可能带来的一些影响。
我的命令的本质是:
public function handle()
{
...
$this->dryRun($modelsToDelete); // Prints info to user
if ($this->confirm('Are you sure you want to delete?') {
$modelsToDelete->each->forceDelete();
}
...
}
public function dryRun($modelsToDelete)
{
...
DB::connection($connection)->beginTransaction();
$before = $this->findAllOrphans($models);
$modelsToDelete->each(function ($record) use ($bar) {
$record->forceDelete();
});
$after = $this->findAllOrphans($models);
DB::connection($connection)->rollBack();
// Print info about diff
...
}
问题是当我做空运行并确认删除时,实际操作并没有持久化在数据库中。如果我注释掉试运行并执行命令,则操作确实会持续。我在试运行和实际运行前后检查了DB::transactionLevel(),一切似乎都是正确的。
我也尝试过使用DB::connection($connection)->pretend(...),但仍然是同样的问题。我还尝试在回滚后执行DB::purge($connection) 和DB::reconnect($connection)。
有人对发生的事情有任何想法吗?
(使用 Laravel v6.20.14)
【问题讨论】:
-
DB::connection($connection)->transaction(function() {}) 祝你好运
-
那里也没有运气@ChinhNguyen
-
你确定你的代码通过了dryRun检查
-
我不确定你的意思@ChinhNguyen?我确实知道试运行会执行并向我显示差异。但是如果我选择实际删除,它不会真正被删除。如果我在没有空运行的情况下运行命令,它实际上会删除它。
-
我还不知道原因,但我找到了解决您问题的方法。当调用 dryRun 时传递 $modelsToDelete 对象的深层副本,例如:$this->dryRun(unserialize(serialize($modelsToDelete)));。我猜是因为在调用 forceDelete() 之后,模型以后不会再查询 delete(只是猜测)
标签: mysql laravel transactions laravel-artisan