Транзакции базы данных Laravel не работают - PullRequest
0 голосов
/ 06 июня 2018

Я пытаюсь настроить транзакцию базы данных в Laravel 5.5, , но, похоже, она не работает.Я использую MySQL 5.7.20, и все таблицы из схемы tools являются InnoDB .Я также использую PHP 7.2.3 .

У меня есть этот код:

DB::beginTransaction();
try {
    // checks whether the users marked for removal are already assigned to the list
    foreach ($removeStudents as $removeStudent) {
        if ($ls->allocatedStudents->find($removeStudent->id) === null) {
            throw new Exception('userNotAllocated', $removeStudent->id);
        } else {
            DB::connection('tools')->table('exercises_list_allocations')
                ->where('user_id', $removeStudent->id)
                ->where('exercises_list_id', $ls->id)
                ->delete();
        }
    }

    // checks whether the users marked for removal are already assigned to the list
    foreach ($addStudents as $addStudent) {
        if ($ls->allocatedStudents->find($addStudent->id) === null) {
            DB::connection('tools')->table('exercises_list_allocations')
               ->insert([
                   'user_id' => $addStudent->id,
                   'exercises_list_id' => $ls->id
               ]);
        } else {
            throw new Exception('userAlreadyAllocated', $addStudent->id);
        }
    }

    DB::commit();
} catch (Exception $e) {
    DB::rollBack();
    return response()->json(
        [
            'error' => $e->getMessage(),
            'user_id' => $e->getCode()
        ], 400
    );
}

И транзакция не откатывается.Если после некоторых удалений или вставок обнаруживается исключение, они не возвращаются.

Сначала я подумал, что это может быть проблемой в MySQL, поэтому я попытался вручную выполнить следующие запросы SQL:

START TRANSACTION;
DELETE FROM tools.exercises_list_allocations WHERE user_id = 67 AND exercises_list_id=308;
DELETE FROM tools.exercises_list_allocations WHERE user_id = 11479 AND exercises_list_id=308;
INSERT INTO tools.exercises_list_allocations (user_id, exercises_list_id) VALUES (1,308);
INSERT INTO tools.exercises_list_allocations (user_id, exercises_list_id) VALUES (2,308);
INSERT INTO tools.exercises_list_allocations (user_id, exercises_list_id) VALUES (3,308);
ROLLBACK;

И он откатывает все удаления и все вставки (как и ожидалось), никаких изменений не происходит с таблицей tools.exercises_list_allocations .Итак, я исключил сервер баз данных как проблему.

Итак, я решил, что это должно быть что-то с кодом PHP.Я искал в Интернете проблемы, схожие с моими, и пробовал некоторые решения, о которых сообщалось.

Я пытался использовать метод DB ::action () с анонимной функцией вместо блока try / catch, но безуспешно.

Я пытался использовать Eloquent ORM вместо методов DB :: insert () и DB :: delete (), оба пытались использовать метод DB ::action () с анонимной функцией и DB :: beginTransaction(), Методы DB :: commit () и DB :: rollBack (), но безуспешно.

Я попытался отключить строковый режим и принудительно заставить InnoDB обработчик в config / database.php, но безуспешно.

Что я делаю не так?Мне нужно, чтобы все удаления и вставки выполнялись в одной атомарной транзакции.

1 Ответ

0 голосов
/ 06 июня 2018

Если вы, как и я, настроили несколько соединений с базой данных в своем приложении, вы должны выбрать соединение перед вызовом методов транзакции, как это предлагается в комментарии ThejakaMaldeniya, если запросы, которые вы хотите выполнить, не находятся в соединении по умолчанию:

DB::connection('tools')->beginTransaction();
DB::connection('tools')->commit();
DB::connection('tools')->rollBack();

И работает отлично.

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