Ошибка при использовании транзакций

275
02 марта 2018, 14:33

Необходимо очистить данные в двух связанных таблицах

Беру пример из учебника и слегка модифицирую

    $transaction = $this->connection->beginTransaction();
    try {
        // $this->connection->createCommand()->truncateTable($this->sectionLangTable)->execute();
        // $this->connection->createCommand()->truncateTable($this->sectionTable)->execute();
        $this->connection->createCommand('SET foreign_key_checks = 0')->execute();
        $this->connection->createCommand('DELETE FROM '.$this->sectionLangTable)->execute();
        $this->connection->createCommand('DELETE FROM '.$this->sectionTable)->execute();
        $this->connection->createCommand('ALTER TABLE '.$this->sectionTable.' AUTO_INCREMENT=1')->execute();
        $this->connection->createCommand('SET foreign_key_checks = 1')->execute();
        $transaction->commit();
        return true;
    } catch (\Exception $e) {
        $error = $e->getMessage();
        $transaction->rollBack();
        return false;
    }

В итоге вылетает с исключением Syntax error or access violation: 1305 SAVEPOINT LEVEL1 does not exist The SQL being executed was: RELEASE SAVEPOINT LEVEL1

Исключение возникает в момент commit или rollback.

Сначала пробовал то что закоменчено - тоже самое.

В гугле в основном результаты с Codeception и его конфигам. Потом идут разговоры о том, что не поддерживает mysql вложенные транзакции.

Но судя по логам транзакция там одна. 2018-02-27 12:04:05 [-][-][-][trace][yii\base\Application::bootstrap] Bootstrap with yii\log\Dispatcher 2018-02-27 12:04:05 [-][-][-][trace][yii\base\Module::getModule] Loading module: gii 2018-02-27 12:04:05 [-][-][-][trace][yii\base\Application::bootstrap] Bootstrap with yii\gii\Module::bootstrap() 2018-02-27 12:04:05 [-][-][-][trace][yii\base\Controller::runAction] Route to run: migrate/up 2018-02-27 12:04:05 [-][-][-][trace][yii\base\InlineAction::runWithParams] Running action: yii\console\controllers\MigrateController::actionUp() 2018-02-27 12:04:05 [-][-][-][trace][yii\db\Transaction::begin] Begin transaction 2018-02-27 12:04:05 [-][-][-][trace][yii\db\Transaction::begin] Set savepoint 1 in D:\www\edusites\htdocs\common\components\sitemap\repository\SitemapRepository.php:156 in D:\www\edusites\htdocs\console\components\migration\handlers\InitialInfoHandler.php:32 in D:\www\edusites\htdocs\console\migrations\data\m180214_092839_menu_initial.php:18 2018-02-27 12:04:05 [-][-][-][trace][yii\db\Transaction::commit] Release savepoint 1 in D:\www\edusites\htdocs\common\components\sitemap\repository\SitemapRepository.php:165 in D:\www\edusites\htdocs\console\components\migration\handlers\InitialInfoHandler.php:32 in D:\www\edusites\htdocs\console\migrations\data\m180214_092839_menu_initial.php:18 2018-02-27 12:04:05 [-][-][-][trace][yii\db\Transaction::rollBack] Roll back transaction in D:\www\edusites\htdocs\common\components\sitemap\repository\SitemapRepository.php:170 in D:\www\edusites\htdocs\console\components\migration\handlers\InitialInfoHandler.php:32 in D:\www\edusites\htdocs\console\migrations\data\m180214_092839_menu_initial.php:18

Данные из таблиц тем не менее чистятся.

Прошу помощи.

P.S. Пока перечитывал пост увидел что в логе нет слова LEVEL а в тексте исключения есть. Может быть в этом беда, но это как-то странно.

P.S.2 тоже самое, но вместо удаления insert - работает хорошо. 2018-02-27 12:24:51 [-][-][-][trace][yii\base\Application::bootstrap] Bootstrap with yii\log\Dispatcher 2018-02-27 12:24:51 [-][-][-][trace][yii\base\Module::getModule] Loading module: gii 2018-02-27 12:24:51 [-][-][-][trace][yii\base\Application::bootstrap] Bootstrap with yii\gii\Module::bootstrap() 2018-02-27 12:24:51 [-][-][-][trace][yii\base\Controller::runAction] Route to run: migrate/up 2018-02-27 12:24:51 [-][-][-][trace][yii\base\InlineAction::runWithParams] Running action: yii\console\controllers\MigrateController::actionUp() 2018-02-27 12:24:52 [-][-][-][trace][yii\db\Transaction::begin] Begin transaction 2018-02-27 12:24:52 [-][-][-][trace][yii\db\Transaction::begin] Set savepoint 1 in D:\www\edusites\htdocs\common\components\sitemap\repository\SitemapRepository.php:155 in D:\www\edusites\htdocs\console\components\migration\handlers\InitialInfoHandler.php:32 in D:\www\edusites\htdocs\console\migrations\data\m180214_092839_menu_initial.php:18 2018-02-27 12:24:52 [-][-][-][trace][yii\db\Transaction::commit] Release savepoint 1 in D:\www\edusites\htdocs\common\components\sitemap\repository\SitemapRepository.php:165 in D:\www\edusites\htdocs\console\components\migration\handlers\InitialInfoHandler.php:32 in D:\www\edusites\htdocs\console\migrations\data\m180214_092839_menu_initial.php:18 2018-02-27 12:24:52 [-][-][-][trace][yii\db\Transaction::commit] Commit transaction

Answer 1

Ваша процедура в принципе не транзакционна. Про этот раздел мануала часто не знают, пока не наткнутся на странное поведение, но и truncate и alter table, как и другие DDL запросы вызывают в mysql неявный коммит.

Коммит (или rollback), явный или нет, моментально освобождает все объявленные savepoint. После этого ваш фреймворк, не учитывающий такую неожиданность, получает закономерную ошибку при работе с уже удалённым savepoint.

READ ALSO
Не могу подключиться ко второй базе данных Laravel

Не могу подключиться ко второй базе данных Laravel

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

238
Не получается настроить кодировку в MySQL

Не получается настроить кодировку в MySQL

Я передаю JsonObject, состоящий из объектов типа String, из android-приложения на сервер через POST-запрос и сохраняю переменные в MySQL c помощью JDBCЕсли в переменных...

180
Удалить поля в MySQL с условием

Удалить поля в MySQL с условием

Добрый деньНеобходимо удалить поля (заменить их значения на NULL), размер которых меньше 10 символов)

189
Удаление последнего символа в MySQL

Удаление последнего символа в MySQL

Добрый день! Возник вопрос, как удалить последний символ (при условии, что этот символ - пробел) в строке (база MySQL)?

295