我可以在数据库事务期间制作一些检查点吗?
例如,当事务开始时,我有许多查询,更新,删除等。
DB::transaction(function () {
DB::table('users')->update(['votes' => 1]);
// something else here
DB::table('posts')->delete();
});
据我了解,如果出现问题,这种函数会自动提交所有内容以及回滚。
但是如果出现错误,是否有可能不回滚所有内容,例如
DB::table('users')->update(['votes' => 1]);
// something else here
DB::if_successful_so_far_do_not_rollback_previous_lines();
DB::table('posts')->delete();
是否存在“小内部提交”?
答案 0 :(得分:3)
是的,你可以。但这也取决于您使用的数据库。
Laravel支持嵌套事务。这与你需要的东西很接近。
要隔离内部事务,必须将其包装在try-catch块中。因此,如果内部事务抛出异常,它将不会到达外部事务,因此继续该过程。但是如果外部事务抛出异常,整个事务(包括其嵌套事务)将回滚。
所以你最终会得到这样的东西:
public function testNestedTransactions()
{
$user = EloquentTestUser::create(['email' => 'taylor@laravel.com']);
$this->connection()->transaction(function () use ($user) {
try {
$this->connection()->transaction(function () use ($user) {
$user->email = 'otwell@laravel.com';
$user->save();
throw new Exception;
});
} catch (Exception $e) {}
$user = EloquentTestUser::first();
$this->assertEquals('taylor@laravel.com', $user->email);
});
}
这是Otwell在this commit implementing the functionality of nested transactions in Laravel写的测试。他首先创建一个用户,然后使用嵌套事务启动一个事务,在那里他更新用户电子邮件,然后抛出一个异常(意味着发生了错误)。在它的正下方,他检查用户的电子邮件在创建时是否仍然保持不变,并且确实如此,因为嵌套事务已经回滚,但外部事务仍然存在。