【问题标题】:Are there any downsides of using a long function in DB::transaction in PHP Laravel?在 PHP Laravel 的 DB::transaction 中使用长函数有什么缺点吗?
【发布时间】:2022-02-18 18:06:19
【问题描述】:

使用 Laravel 作为我的后端,我想通过控制器将数据添加到我的数据库中。为此,我需要做两件事:

  1. 验证数据并使用函数A将数据插入到tableA中。函数A返回接收到的id

  2. 更新用户使用函数B提交tableB中的数据。tableB通过tableA->id与tableA相关。

我希望上述两个步骤在数据库事务中运行。例如,如果更新 tableB 时出现错误,理想情况下应该回滚 tableA。我认为这是最有意义的?

但是,如果 functionA 因为需要验证数据而不必要地长,例如这里:

public function A($data) {
    // get data constraints from tableC (a get query)
    // verify data against constraints stated in tableC (assume this step is long)
    // insert data into tableA
    // return row Id.
}

public function B($userId, $rowId) {
    // update tableB where userId = $userId with $rowId.
}

public function controller(Request $request) {
    DB::transaction(function() use ($request) {
        $newId = A($request->data);
        B($request->userId, $newId);
    });
}

据我了解,这并不理想。因为函数 A 会占用事务时间来执行其他操作,例如查询表和执行循环以验证数据。

这会导致不必要的工作量被包含在 DB::transaction 中。

我想知道这真的是一件坏事吗? DB::transaction 是否以可以优化任何表锁定的方式实现?

我不能轻易改变逻辑的结构,因为函数 A 和函数 B 属于两个不同的类。

编辑: 如果我真的愿意,我实际上可以更改逻辑,但是现在我更感兴趣的是这是否真的是使用 DB::transaction 的问题。

因为现在我什至不确定 DB::transaction 是否会为整个函数锁定表。

【问题讨论】:

标签: php laravel


【解决方案1】:

DB::transaction 不锁定表。只有当块内抛出异常时,它才会回滚更改。

欲了解更多信息:https://laravel.com/docs/9.x/database#database-transactions

如果你想锁定表,你可以使用这个问题的答案:How to lock table with Laravel?

DB::raw('LOCK TABLES important_table WRITE');

【讨论】:

  • 好吧,既然 DB::transaction 没有锁表,那我的长查询也没关系!
猜你喜欢
  • 2011-02-27
  • 1970-01-01
  • 1970-01-01
  • 2017-01-03
  • 1970-01-01
  • 1970-01-01
  • 2016-03-18
  • 1970-01-01
  • 2011-06-29
相关资源
最近更新 更多