如果发生错误,如何避免插入数据? Laravel 中的(多次插入的方法)

How to avoid data insertion if an error occurs? (method with several insertions) in Laravel

我正在构建 Web 应用程序,我知道一个可能的问题。

我有一个控制器,其中有一个 store 方法。此方法在数据库中创建多个插入。

public function store(LocationPostRequest $request)
{
  $location = Location::create([...]);
  $order = new Order([...]);
  $location->order()->save($order);
  $contact = Contact::findOrFail(id);
  $order->contacts()->save($contacts);
  Transaction::create([])
}

如你所见,我有很多插入。

如果发生错误(或者如果用户在某个时候断开连接),它将破坏我的数据库的完整性,因为我的方法将添加第一个元素而不是其他元素。

我这样想对吗? 如何避免这种情况?

您可以使用 laravel 数据库事务。

如果任何数据库查询失败,它将自动回滚以前的查询。
DB::transaction(function () {
    //set of queries
   //example 
   DB::table('users')->update(['votes' => 1]);
   DB::table('posts')->delete();
});

是的,你完全正确。您关心的是数据库的一般问题。经典的例子是银行转账,就是你把钱汇给我。该金额需要从您的钱中减去并添加到我的钱中。如果第一次操作失败,那就是运气不好,但至少没有人赔钱。如果它在中间某个地方失败了,在从你那里减去钱之后,但在它被添加到我之前,那么你将很难说服我你实际上已经发送了金额,而你已经失去了给定的金额。

您的情况类似,可能风险较小,但仍然重要的是确保在出现故障时恢复操作之前的数据库状态。这就是一些操作应该彼此形成原子绑定并且它们应该一起成功或一起失败的想法的来源。这种结合在一起的操作称为 transaction.

您可能使用的 RDBMS 实例支持事务,请参阅 https://www.tutorialspoint.com/dbms/dbms_transaction.htm

交易是:

  • Atomic
  • C坚持
  • D耐用
  • 孤独

这些共同构成了ACID原理,是你在烦恼中凭直觉发现的。 Laravel has its own support 用于交易,您可以通过

调用
DB::transaction($somefunction)

您的工作是将您的函数作为参数传递给 DB::transaction,不要担心,因为万一失败 Laravel 声称会发生回滚。我当然会测试,因为,正如温斯顿丘吉尔所说:

However beautiful the strategy, you should occasionally look at the results.

您可以将 try 和 catch 与 DB:transaction() 一起使用。

try {
        //start the transaction
        DB::beginTransaction();

        //You code

        //commit the transaction
        DB::commit();
} catch (\Exception $e) {
        DB::rollBack();
        return response;
}

希望对您有所帮助