【问题标题】:Laravel DB::rollback() doesn't work for transaction processesLaravel DB::rollback() 不适用于事务处理
【发布时间】:2018-05-11 12:03:45
【问题描述】:

首先我的引擎是 innoDB,我已经在 mySQL 上尝试了以下内容:

BEGIN;
INSERT INTO `tbl_users`(...) VALUES (...)
ROLLBACK();

它工作正常,这意味着问题不在我的 mysql 配置中。

但是当我在我的 Laravel 模型上尝试这个时:

public static function addNew($request, $department_id) {

    $result = array();

    $now = Carbon::now();

    DB::beginTransaction();

    //Checking for existing Order to set appropriate starting ID
    $result = DB::select("
        SELECT COUNT(`id`) AS 'count'
        FROM `tbl_consignmentorders`
    ")[0];

    if($result->count == 0){
        DB::update("ALTER TABLE `tbl_consignmentorders` AUTO_INCREMENT = 70000000001;");
    }

    try {
        //INSERT
        DB::insert("
            INSERT INTO `tbl_consignmentorders`
            (`from`, `to`, `status`, `created_at`, `updated_at`) 
            VALUES 
            (?, ?, ?, ?, ?)",
            [
                $department_id,
                strtoupper($request->input('supplier')),
                'PENDING',
                $now,
                $now
            ]
        );
        //GET THE LAST ID INSERTED, NEEDED FOR NEXT INSERT
        $last_id = DB::select("
            SELECT 
                LAST_INSERT_ID() AS 'id'
            FROM `tbl_consignmentorders`;"
        )[0]->id;

        //CONSTRUCTING QUERY STRING FOR VALUES
        $values = '';
        $count = 0;
        foreach($request->input('item_id') as $item) {
            $values .= ',(' . $request->input('quantity')[$count] . ', ' . $last_id . ', ' . $item . ', ' . $request->input('item_price_id')[$count] . ' )';
            $count++;
        }
        $values[0] = ' ';

        //INSERT TO DETAILS
        DB::insert("
            INSERT INTO `tbl_consignmentorderdetails`
            (`quantity`, `order_id`, `item_id`, `item_price_id`) 
            VALUES 
            $values;"
        );

        //INSERT TO TRANSACTION AUDIT
        DB::insert("
            INSERT INTO `tbl_transactions`
            (`type`, `reference_id`, `department_id`, `created_at`, `updated_at`) 
            VALUES 
            (?, ?, ?, ?, ?)",
            [
                'CONSIGNMENT ORDER',
                $last_id,
                $department_id,
                $now,
                $now
            ]
        );

        //COMMIT NOTHING FAILS
        DB::commit();
        $result = true;

    } catch (\Exception $e) {
        //ROLLBACK SOMETHING IS WRONG
        DB::rollback();
        $result = $e->getMessage();
    }

    return $result;
}

现在上面的代码在成功的时候可以正常工作,现在要产生错误,我会故意改变这部分代码:

    //GET THE LAST ID INSERTED, NEEDED FOR NEXT INSERT
    $last_id = DB::select("
        SELECT 
            LAST_INSERT_ID() AS 'id'
        FROM `tbl_consignmentorders`;"
    )[0]; //<--- I removed the ->id to return the whole object causing object to string error on the next query

现在正如预期的那样,它会转到 catch 块来传递错误消息,但是在错误之前执行的查询仍然存在于数据库中它不应该存在的地方。

【问题讨论】:

    标签: database laravel transactions laravel-5.5


    【解决方案1】:

    大多数人对DB::rollback 不起作用的问题是他们没有首先启动DB::transaction 函数!

    DB::rollback 仅在事务启动时有效

    可以通过两种方式启动事务:

    1. 在方法中使用 DB::transaction 函数

      DB::transaction(function () {
          DB::table('users')->update(['votes' => 1]);
      
          DB::table('posts')->delete();
      });
      
    2. 通过在方法开始时手动启动事务,并且可能在调用外部 API 失败时,您调用 DB::rollback() 方法

      DB::beginTransaction();
      
      DB::rollBack();
      

    【讨论】:

      【解决方案2】:

      如果你的系统使用多个数据库配置,你需要做这样的事情

      DB::connection('database_config_2')->beginTransaction();
      DB::connection('database_config_2')->rollback();
      DB::connection('database_config_2')->commit();
      

      希望对你有帮助!

      【讨论】:

        【解决方案3】:

        我的错,

        我使用DB::rollback(); 而不是DB::rollBack(); 大写B

        【讨论】:

          猜你喜欢
          • 2013-02-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多