我认为这笔交易只是被丢弃了。这个说法准确吗?
我正在使用mysql。
例如:
try {
DB::beginTransaction();
throw new Exception("something happened");
DB::commit()
} catch (Exception $e) {
Log::debug("something bad happened");
}
谢谢
如果您正在使用闭包,例如:
DB::transaction(function () {
DB::table('users')->update(['votes' => 1]);
DB::table('posts')->delete();
});
您将在框架内运行此代码:
public function transaction(Closure $callback)
{
$this->beginTransaction();
// We'll simply execute the given callback within a try / catch block
// and if we catch any exception we can rollback the transaction
// so that none of the changes are persisted to the database.
try {
$result = $callback($this);
$this->commit();
}
// If we catch an exception, we will roll back so nothing gets messed
// up in the database. Then we'll re-throw the exception so it can
// be handled how the developer sees fit for their applications.
catch (Exception $e) {
$this->rollBack();
throw $e;
} catch (Throwable $e) {
$this->rollBack();
throw $e;
}
return $result;
}
因此,在这种情况下,您可以100%确定交易将会回滚。如果您手动使用 DB::beginTransaction();
开启事务,则无法确保它会回滚,除非您通过类似以下方式进行确认:
try {
DB::beginTransaction();
//do something
DB::commit();
} catch (\Exception $e) {
DB::rollback();
}
如果您在没有捕获异常的情况下抛出异常,脚本将会停止或以打开的事务结束,PDO 将自动回滚 (http://php.net/manual/zh/pdo.transactions.php):
当脚本结束或连接即将关闭时,如果存在未完成的事务,PDO 将自动回滚。
没有被提交的事务将在 SQL 中被丢弃。
当您在此处抛出异常时,DB::commit()
永远不会被执行。您将直接进入 catch() 块,因此事务将被丢弃(只要 DB::commit()
在后面没有被调用)。
然而,我仍然建议在 catch 块中显式地回滚事务,如果您不想在抛出异常时提交事务的话。这将关闭该事务并防止对该执行中未来的查询产生任何影响。
try {
DB::beginTransaction();
throw new Exception("something happened");
DB::commit()
} catch (Exception $e) {
Log::debug("something bad happened");
DB::rollBack();
}
或者使用内置的DB::transaction()方法,结合闭包函数,在未捕获异常时自动回滚事务。具体文档请参考:https://laravel.com/docs/5.3/database#database-transactions