0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LaravelAdvent Calendar 2024

Day 18

laravel delete()だとエラーにならずtruncate()だとエラーになる処理

Posted at

概要

laravelのとあるDBのデータ削除処理にてdelete()だとエラーは出ず、truncate()だとエラーが出るので原因を調査してみた。

前提

DBはMySQL

エラーが出る状態のコードを下記に記載する。
トランケート対象テーブル名はhogesでモデルクラス名はHogeである。
hogesテーブルに外部キー制約は無い。
トランケートを選んだ理由は「パフォーマンス良い」「中身が消せればいい」程度。

try {
    DB::beginTransaction();

    // その他の処理

    Hoge::truncate();

    DB::commit();
} catch (\Exception $e) {
    DB::rollBack();
    throw $e;
}

上記の処理を実行すると下記のエラーがでる。

There is no active transaction (意訳:「アクティブなトランザクションが無い」)

解消方法

下記の様にtruncate()ではなくdelete()を利用する。

try {
    DB::beginTransaction();

    // その他の処理

    Hoge::query()->delete;

    DB::commit();
} catch (\Exception $e) {
    DB::rollBack();
    throw $e;
}

もしくはトランザクションを使わずtruncate()を利用する。

エラーの原因

下記の記事でまとめたようにtruncate()はSQLのTRUNCATE TABLE句を実行している。

そしてMySQLの場合のTRUNCATE TABLE句は内部で暗黙的にトランザクションとコミットを行っておりロールバック非対応だ。

あくまで予想であるが今回自身が意図定期にtry catchの中でDB::beginTransaction();を宣言しトランザクションを開いたが、truncate()が実行したTRUNCATE TABLE句によってこのトランザクションが閉じられ、DB::commit();で閉じるトランザクションが見当たらなかったのではないか。

実際にlaravelのエラー画面でもDB::commit();でエラーが出ていることがわかる。

CleanShot 2024-12-27 at 20.21.44@2x.png

参考文献

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?