LoginSignup
11
11

More than 5 years have passed since last update.

Laravelのトランザクションはネストできる

Last updated at Posted at 2017-12-01

一部のRDBだけできるトランザクションのネストに対応してるってわけじゃなくて擬似的にネストさせてる。

内部的にトランザクションのカウント取っていて、
一番外側の \DB::commit() もしくは \DB::rollback() のみ実行される。

他のフレームワークでもこういう仕組み結構ありそう。

function tranA()
{
    \DB::transaction(function ()
        \DB::insert("QueryA");
        tranB(); // 別のトランザクション使った関数呼び出し
    });
}

function tranB()
{
    \DB::transaction(function ()
        \DB::insert("QueryB");
    });
}

tranA() を呼ぶと BEGIN --> QueryA --> QueryB --> COMMIT となるし、
tranB() を呼ぶと BEGIN --> QueryB --> COMMIT となる。

以下も同様

function tranA()
{
    \DB::beginTransaction();

    try {
        \DB::insert("QueryA");
        tranB(); // 別のトランザクション使った関数呼び出し
        \DB::commit();

    } catch (\Throwable $ex) {
        \DB::rollback();
        throw $ex;
    }
}

function tranB()
{
    \DB::beginTransaction();

    try {
        \DB::insert("QueryB");
        \DB::commit();

    } catch (\Throwable $ex) {
        \DB::rollback();
        throw $ex;
    }
}

と、ここまで書いておいてなんだけど個人的には使わないほうがいいと思う
理由は以下

  • コード追いかけてると「ファッ?!!!」って多くの人がなりそう
  • 書き方によってはQueryAだけ成功とかQueryBだけ成功ってケースができそう(思いつかなかった
  • トランザクションってRDBに対するひとまとまりの処理だからなんかヤダ

おまえ、もしかしてまだ、beginTransactionが死なないとでも思ってるんじゃないかね?

同じような書き方すると下記のような感じ。

function tranA()
{
    try {
        \DB::beginTransaction();
        \DB::insert("QueryA");
        tranB();
        \DB::commit();

    } catch (\Throwable $ex) {
        \DB::rollback();
        throw $ex;
    }
}

function tranB()
{
    try {
        \DB::beginTransaction(); // ここで失敗したとき
        \DB::insert("QueryB");
        \DB::commit();

    } catch (\Throwable $ex) {
        \DB::rollback();
        throw $ex;
    }
}

tranA() を呼び出して tranB()beginTransaction() で失敗すると、
その下の rollback() に対応してるのは tranA()beginTransaction() だぞ!!

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