Lumen 5.1.3 で統合テストを作成しています。私のテストのほとんどは、トランザクションを正常にロールバックします。以下は、成功したロールバックがどのように見えるかをまとめたものです (コードを単純化しています。実際には、トランザクション管理は、PHPUnit の @before アノテーションにアタッチした特性を介して行われます)。
DB::beginTransaction();
DB::table('user')->insert(
[
'guid' => $guid,
'username' => $username,
'email' => $email,
'status' => USER_STATUS_ACTIVE,
'type' => USER_TYPE_REGULAR,
'created_on' => $currentDateTime
]
);
DB::rollBack();
すべてが良いです。このテストの後、ユーザー テーブルは空です。
さて、ここで私は混乱します。ミックスに SP を追加すると、ロールバックされません。
DB::beginTransaction();
DB::table('user')->insert(
[
'guid' => $guid,
'username' => $username,
'email' => $email,
'status' => USER_STATUS_ACTIVE,
'type' => USER_TYPE_REGULAR,
'created_on' => $currentDateTime
]
);
DB::statement('CALL s_generate_leaderboards(?)', [$oneWeekAgo]);
DB::rollBack();
新しい User レコードは実際にコミットされています。DB::rollBack();
ストアド プロシージャを実行すると、効果がありません。
エラーはありません - すべてが成功します。DB::rollBack();
コマンドに到達していることも確認し ました。
では、SP を呼び出した場合にのみトランザクションがコミットされるのはなぜですか? とてもイライラする.. :(
編集1:
あなたの疑いは的中しました。これがSPです(大きいので90%折りたたんでいます):
CREATE PROCEDURE s_generate_leaderboards (IN week_ago_date DATETIME)
BEGIN
-- Empty and regenerate the all-time leaderboard:
TRUNCATE TABLE all_time_leaderboard;
INSERT INTO all_time_leaderboard (...)
...;
-- Empty and regenerate last week's leaderboard:
TRUNCATE TABLE last_week_leaderboard;
INSERT INTO last_week_leaderboard (...)
...;
END
TRUNCATE
おそらく、コミットしているのは SP 自体ではなく、SP内のステートメントのみでしょうか?
TRUNCATE
が使用されているのはposition
、リーダーボード テーブルに自動インクリメントする列があり、リセットする必要があるためです。DELETE FROM table
自動インクリメントをリセットしません..