- 方式一:闭包方式实现事务
您可以在 DB facade 上使用 transaction 方法,在数据库事务中运行一组操作。如果在事务 Closure 中抛出一个异常,那么事务将自动回滚。如果 Closure 成功执行,事务将自动被提交。您不需要担心在使用事务方法时手动回滚或提交。
//模拟用户233向用户666转账1元
DB::transaction(function () {
DB::table('transactions')->where('user_id',666)increment('blance' , 1);
DB::table('transactions')->where('user_id',233)->decrement('balance' , 1);
});
transaction 方法接受一个可选的第二个参数,该参数定义在发生死锁时,应该重新尝试事务的次数。一旦这些尝试都用尽了,就会抛出一个异常.
如果闭包内部需要调用外部的参数可以使用下面的方式向闭包传参
DB::transaction(function use ($amount) () {
DB::table('transactions')>where('user_id',666)increment('blance' , $amount);
}
- 方式二:手动操作事务
如果您想要手工开始一个事务,并且对回滚和提交有完全的控制,那么您可以在 DB facade 上使用:
beginTransaction 方法
DB::beginTransaction();
您可以通过 rollBack 方法回滚事务:
DB::rollBack();
最后, 您可以通过 commit 方法提交事务,当事务进行提交(commit)或者回滚(rollBack)时都会取消锁:
DB::commit();
例子如下:
DB::beginTransaction(); //开启事务
try {
//这里省略了业务逻辑代码
if($isSuccess){
DB::commit(); //成功,提交事务
}
//思考->如果事务开启不提交会发生什么后果???
} catch(\Illuminate\Database\QueryException $ex) {
DB::rollback(); //失败,回滚事务
echo 'error';
}
echo 'success';
如果MySQL存在没有提交的事务,那么这时候 AUTOCOMMIT 自动提交的参数应该是为 0 的。如果通过其他的语言的MySQL驱动来操作的话,这些驱动一般都带有自动恢复 AUTOCOMMIT 的功能,在请求处理完成后会自动 ROLLBACK 没有处理的事务。