如果在laravel5中没有DB :: commit()调用DB :: beginTransaction会发生什么?

时间:2016-12-23 04:37:27

标签: php laravel laravel-5 transactions

Normall,在使用DB::beginTransaction()时,它与DB::rollBack()

一起使用

这样的事情:

DB::beginTrnsaction();
try {
    DB::insert(...);
    DB::insert(...);
    DB::insert(...);

    DB::commit();
    // all good
} catch (\Exception $e) {
    DB::rollback();
    // something went wrong
}

但是,如果我忘记添加try catch循环怎么办?

DB::beginTrnsaction();
DB::insert(...);
DB::insert(...);
DB::insert(...);
DB::commit();

如果其中一个插件出错,是否会更改数据库?或者它会自动回滚?

2 个答案:

答案 0 :(得分:1)

如果您启动了一个事务,但从未提交或回滚,则在关闭与数据库的连接时,事务将自动回滚。

对于大多数PHP页面来说,这不是什么大问题,因为一旦请求完成,连接通常会关闭。

但是,如果使用持久连接,则会出现问题。使用持久连接时,请求完成后,与数据库的连接不会结束。连接返回到连接池,活动良好,并且事务仍然打开。在事务仍然打开的情况下,记录上的锁仍处于活动状态,这可能会阻止对以下请求的访问,直到连接终止并且流氓事务可以回滚。

说到交易,它们越短越好。您希望交易活得足够长,以完成您的工作单元,但您不希望它比这更长久。只要您可以提交或回滚以完成事务,其他进程必须等待获取这些记录锁定的时间就越短。这确实会影响大量网站。

你可以做的一件事就是把责任从自己身上移开,就是在传递给Closure方法的transaction()内做你的工作。这将自动处理事务的启动和提交/回滚。

DB::transaction(function () {
    DB::insert(...);
    DB::insert(...);
    DB::insert(...);
});

如果在Exception内抛出任何Closure,则回滚该事务。否则,事务将提交。

答案 1 :(得分:0)

尝试理解这个概念:

BEGIN TRANSACTION - >从DB

的最后一个编组状态开始

您的代码

if($condition)
{
    // ROLLBACK
}
else
{
    // COMMIT
}

ROLLBACK 表示撤消所做的所有更改,并从上一个一致状态开始。

COMMIT 表示一切正常,您希望保存更改以使其持久。

注意:如果您未提交,则删除所有更改。