Как избежать вставки данных в случае ошибки? (метод с несколькими прошивками) в Laravel - PullRequest
1 голос
/ 10 июля 2020

Я создаю веб-приложение и знаю о возможной проблеме.

У меня есть контроллер, в котором есть метод 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([])
}

Как видите, у меня много вставок.

Если происходит ошибка (или если пользователь теряет соединение в какой-то момент), это нарушит целостность моей базы данных, потому что мой метод добавит первые элементы, но не остальные.

Правильно ли я так думаю? Как этого избежать?

Ответы [ 3 ]

3 голосов
/ 10 июля 2020

Вы можете использовать laravel преобразование базы данных.

если какой-либо запрос к базе данных завершился неудачно, он автоматически откатит предыдущий запрос.
DB::transaction(function () {
    //set of queries
   //example 
   DB::table('users')->update(['votes' => 1]);
   DB::table('posts')->delete();
});
1 голос
/ 10 июля 2020

Да, вы совершенно правы. Вас беспокоит общая проблема с базами данных. Классический пример - банковский перевод, когда вы отправляете мне деньги. Сумму нужно уменьшить с ваших денег и добавить к моей. Если он не сработает при первой операции, то это неудача, но, по крайней мере, никто не теряет деньги. Однако если где-то посередине произойдет сбой, после того, как деньги будут вычтены из вас, но до того, как они будут добавлены мне, вам будет трудно убедить меня, что вы действительно отправили сумму, в то время как вы потеряли данную сумму.

Ваш сценарий похож, может быть, меньше поставлено на карту, но все же важно убедиться, что состояние вашей базы данных до ваших операций восстанавливается в случае сбоя. Это то, что породило идею, что некоторые операции должны образовывать атом c, связанный друг с другом, и они должны либо успешно работать вместе, либо терпеть неудачу вместе. Эта объединяющая операция называется транзакция .

Транзакции поддерживаются в экземплярах СУБД, которые вы, вероятно, используете, см. https://www.tutorialspoint.com/dbms/dbms_transaction.htm

Транзакции :

  • A tomi c
  • C постоянный
  • D urable
  • I solated

Все вместе они образуют принцип КИСЛОТЫ, который вы интуитивно обнаружили в своем беспокойстве. Laravel имеет собственную поддержку для транзакций, которую вы можете вызвать через

DB::transaction($somefunction)

Ваша задача - передать вашу функцию в качестве параметра в DB::transaction и не беспокойтесь, потому что в в случае сбоя Laravel заявляет, что произойдет откат. Я бы, конечно, проверил, потому что, как сказал Уинстон Черчилль:

Какой бы красивой ни была стратегия, вам следует время от времени смотреть на результаты.

0 голосов
/ 10 июля 2020

Вы можете использовать try and catch вместе с DB: transaction ().

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

        //You code

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

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...