3
1

More than 3 years have passed since last update.

LaravelのUnitテストでRefreshDatabaseを使ったらSAVEPOINT trans2 does not exist が出た話

Posted at

現象

Laravelを利用した環境で通常のケースではTransactionも機能しており問題なかったが、RefreshDatabaseを用いたPHPUnitでの実行ではエラーが発生していた。

Doctrine\DBAL\Driver\PDOException : SQLSTATE[42000]: Syntax error or access violation: 1305 SAVEPOINT trans2 does not exist
 /src/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:43
 /src/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php:260
 /src/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php:238
 /src/vendor/laravel/framework/src/Illuminate/Foundation/Testing/RefreshDatabase.php:90
 /src/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php:233
 /src/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php:149

 Caused by
 PDOException: SQLSTATE[42000]: Syntax error or access violation: 1305 SAVEPOINT trans2 does not exist

 /src/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:41
 /src/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php:260
 /src/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php:238
 /src/vendor/laravel/framework/src/Illuminate/Foundation/Testing/RefreshDatabase.php:90
 /src/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php:233
 /src/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php:149

環境

全てdockerコンテナ内

  • mysql: 5.7
  • Laravel: 6.18.34
  • PHPUnit: 9.3.0

先に結論

調査方法

  • MySQLのクエリログを有効にする
[mysqld]
general_log=ON 
general_log_file=general_query.log
  • テストを実行する
  • /var/lib/mysql/general_query.log を確認
  • QueryとExecuteだけ抜き出し

今回はこの時点でSTART TRANSACTION後にテーブルのtruncateを行っていた事に気づけたが一応MySQLコンソールにクエリ流し込んでエラーになることを確認したりもした。

あとがき

LaravelのRefreshDatabaseでRollback出来ない、Transactionがおかしいみたいな内容はググると結構出てくるが、結局きちんと解決しているものが少ないように思えたので残してみることにした。

はじめはLaravel側でクエリログを出力していたが、SAVEPOINT周りなんかはTransactionRolledBackTransactionCommittedTransactionBeginningで追いきれなかったのでMySQL側でログ出力したほうが確実だったなと後から反省。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1