Laravel DB::rollback() 不适用于事务处理
Posted
技术标签:
【中文标题】Laravel DB::rollback() 不适用于事务处理【英文标题】:Laravel DB::rollback() doesn't work for transaction processes 【发布时间】: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 块来传递错误消息,但是在错误之前执行的查询仍然存在于数据库中它不应该存在的地方。
【问题讨论】:
【参考方案1】:大多数人对DB::rollback
不起作用的问题是他们没有首先启动DB::transaction
函数!
DB::rollback
仅在事务启动时有效
可以通过两种方式启动事务:
在方法中使用 DB::transaction 函数
DB::transaction(function ()
DB::table('users')->update(['votes' => 1]);
DB::table('posts')->delete();
);
通过在方法开始时手动启动事务,并且可能在调用外部 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
【讨论】:
以上是关于Laravel DB::rollback() 不适用于事务处理的主要内容,如果未能解决你的问题,请参考以下文章
yajra/laravel-datatables 搜索不适用于 laravel 5.4