5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

LaravelのtransactionでrollBack時処理をハンドリング出来るようにする

Posted at
  • 初版:2018.12.12
  • laravel-5.7, php-7.2

開発中や特別なトランザクションで、rollback時の処理を追加したくなるときがある。laravelのDB::transaction() はrollback時処理を拡張できないし、DB::beginTransaction/commit/rollBack三兄弟をベタに使うとテストしづらいので、ヘルパー的なものを用意する。

単純に、rollback時共通でロギングするだけなら、Laravelのイベント機能を使ってrollbackイベントをListenして実行する方が良いでしょう。

ラッパークラス的な
<?php
/**
 * transaction wrapper
 */
namespace App\ORM\Helpers;

use Illuminate\Support\Facades\DB;

class Transaction
{
    /**
     * DB::transactionはrollbackをハンドリングできないので、処理足す
     * @param \Closure $process () no args
     * @param \Closure $rollbacker ($rollback, $e) invoke $rollback() means DB::rollBack();
     */
    public static function do(\Closure $process, \Closure $rollbacker = null)
    {
        $result = null;

        if (is_callable($rollbacker)) {
            // rollback指定あり
            DB::beginTransaction();
            try {
                $result = $process();
                DB::commit();
            } catch (\Exception $e) {
                $rollbacker(function () {
                    DB::rollBack();
                }, $e);
            }

        } else {
            // 指定なし
            $result = DB::transaction(function () use ($process) {
                return $process();
            });
        }
        return $result;
    }
}
呼び出し側

$eloquentInstance = Transaction::do(function () {
    // DB::insert とか Eloquent::create とか

    // ここのreturnの値がそのまま上での返り値となる
    return $createdEloquentInstance;

}, function ($rollback, $e) {
    // file_put_contents();でログするとかなにか特別な処理
    $rollback();
    // throw new \Exception(); とかなにか特別な処理
});


DB::transaction() をtry-catchで囲めばrollback後の処理は対応できるけど、ネストが深くなるのがいや。

ネストが深い
try {
    DB::transaction(function () {
        // nest fukai
    });
} catch (\Exception $e) {
   // after rollback
}

5
4
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
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?