$pdo->beginTransaction(); | commit(); | rollback(); || Один на “prepare->()” или один на код?

Вопрос или проблема

Должен ли я вызывать beginTransaction / Commit для каждого prepare->(“”) выражения? Или только один раз для всего кода?

Я пишу довольно объемный код таким образом, но беспокоюсь, что, когда я закончу, всё будет некорректно. Как мне правильно поступить?

Пример:

self::$pdo->beginTransaction();
$cmd = self::$pdo->prepare("
INSERT INTO historico_horas (id_data, id_colab, atrasos, data_ocorrencia, data_registro) VALUES (:iddata, :id, :qnt_atrasos, :dataocorrencia, :dataregistro)");

$id_data_gerado = self::$pdo->lastInsertId();
$cmd->bindParam(":iddata", $id_data_gerado);
$cmd->bindParam(':id', self::$ColabId);
$cmd->bindParam(':qnt_atrasos', $totalMinutos);
$cmd->bindParam(':dataocorrencia', $d_ocorr);
$cmd->bindParam(':dataregistro', self::$dataRegistro);

if ($cmd->execute()) {
    if ($_ENV['APP_ENV'] == "development") {
        self::$logger->info('Данные успешно зафиксированы в базе данных.');
    }
    self::$pdo->commit();
    Alert::Alert("AtrasoCad");
    exit();
} else {
    if ($_ENV['APP_ENV'] == "development") {
        self::$logger->info('Не удалось зафиксировать данные в истории.');
    }
    self::$pdo->rollBack();
}
exit();

Ответ или решение

Вопрос о том, как правильно использовать транзакции в PDO (PHP Data Objects), имеет важное значение, особенно когда вам необходимо выполнять несколько операций вставки или обновления с целью поддержания целостности данных. Давайте подробно рассмотрим использование методов beginTransaction(), commit(), и rollback().

Правильное использование транзакций

  1. Транзакция на уровне блока операций: Вам не следует вызывать beginTransaction() и commit() для каждой отдельной операции или prepare(); вместо этого следует использовать их на уровне логического блока операций. Это означает, что вы начинаете транзакцию с beginTransaction(), выполняете несколько операций, и затем, если все прошло успешно, вызываете commit(), а в случае ошибки — rollback(). Это позволяет группе связанных изменений быть атомарными, т.е. все изменения будут согласованными или не будут применены вовсе.

  2. Ваш пример: В вашем коде вы используете транзакцию правильно, но есть некоторые моменты, которые можно улучшить. Например, если у вас несколько запросов, вы хотите, чтобы все они выполнялись в рамках одной транзакции.

Пример многократных операций

self::$pdo->beginTransaction();

try {
    $cmd1 = self::$pdo->prepare("
    INSERT INTO historico_horas (id_data, id_colab, atrasos, data_ocorrencia, data_registro) 
    VALUES (:iddata, :id, :qnt_atrasos, :dataocorrencia, :dataregistro)");

    // Привязка параметров
    $cmd1->bindParam(":iddata", $id_data_gerado);
    $cmd1->bindParam(':id', self::$ColabId);
    $cmd1->bindParam(':qnt_atrasos', $totalMinutos);
    $cmd1->bindParam(':dataocorrencia', $d_ocorr);
    $cmd1->bindParam(':dataregistro', self::$dataRegistro);

    // Выполнение первого запроса
    if (!$cmd1->execute()) {
        throw new Exception('Ошибка при выполнении первого запроса');
    }

    // Дополнительные операции могут быть выполнены здесь
    // Например, другой запрос:
    $cmd2 = self::$pdo->prepare("INSERT INTO другая_таблица (столбец1, столбец2) VALUES (:значение1, :значение2)");
    // Привязка и выполнение cmd2...

    // Если все прошло успешно
    self::$pdo->commit();
} catch (Exception $e) {
    // Если что-то пошло не так, откатим изменения
    self::$pdo->rollBack();
    if ($_ENV['APP_ENV'] == "development") {
        self::$logger->error('Транзакция откатана: ' . $e->getMessage());
    }
}

Заключение

  • В одном блоке: Всегда используйте одну транзакцию на логический блок операций, а не для каждого запроса отдельно.
  • Исключения: Обрабатывайте исключения корректно, чтобы обеспечить откат в случае ошибок.
  • Логирование: Используйте логирование для отслеживания действий и ошибок, это поможет в отладке и мониторинге.

Следование этим рекомендациям поможет вам эффективно управлять транзакциями в вашем приложении и гарантировать целостность данных.

Оцените материал
Добавить комментарий

Капча загружается...