@Super0leg

PDO Почему не откатываются транзакции?

Есть код:
$dsn = 'mysql:host=localhost;dbname=dbname;charset=utf8';
        $opt  = array(
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES   => TRUE,
        );
        $db = new PDO($dsn, DB_USER, DB_PASS, $opt);
        try {
            $db->beginTransaction();
            $db->exec('UPDATE `users` SET `money` = \'' . $money_m . '\', `money_frozen` = \'' . $money_frozen_m . '\' , `money_hash` = \'' . $hash_m . '\' WHERE `users`.`id` = ' . $id_user . ';');
            $db->exec('INSERT INTO `money_transactions` (`id`, `user_id`, `sum`, `comission`, `now_sum`, `translation_to_user`, `comment`, `status`, `ip`, `datetime`) VALUES (NULL, ' . $id_user . ', ' . $money . ', NULL, \'' . $money_m . '\', NULL, '.$comment.', \'Выполнен1\', INET_ATON(\'' . $_SERVER["REMOTE_ADDR"] . '\'), NOW());');

            $db->exec('запрос с ошибкой');
            exit('Допущенная ошибка');
            $db->exec('INSERT INTO `money_transactions` (`id`, `user_id`, `sum`, `comission`, `now_sum`, `translation_to_user`, `comment`, `status`, `ip`, `datetime`) VALUES (NULL, ' . $id_user . ', ' . $money . ', NULL, \'' . $money_m . '\', NULL, '.$comment.', \'Выполнен2\', INET_ATON(\'' . $_SERVER["REMOTE_ADDR"] . '\'), NOW());');
            $db->commit();

        } catch(PDOException $e) {
            $db->rollBack(); // тут транзакция не откатывается
            $this->send_error($id_user, 'Не удалось совершить транзакцию');
            return false;
        }


Срабатывают 2 первых запроса, срабатывает исключение, но rollBack не откатывает транзакцию
  • Вопрос задан
  • 586 просмотров
Решения вопроса 1
FanatPHP
@FanatPHP
Чебуратор тега РНР
Скорее всего движок БД не поддерживает транзакции. Надо поменять у таблиц engine с myisam на innodb

Напомню, что необходмо ловить \Exception, а не PDOException. Нам без разницы, какая именно ошибка прервала выполнение транзакции, откатываться надо в любом случае.

Плюс никогда нельзя забывать о логировании ошибок. То есть, вместо return false;, которое совсем ни о чем, лучше перевыбросить исключение, чтобы оно могло быть обработкно стандартным образом. В общем, читайте правильные мануалы, там все есть :)
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы