Laravel如何使用数据库事务及捕获事务失败后的异常详解


Posted in PHP onOctober 23, 2017

前言

如果大家在Laravel中要想在数据库事务中运行一组操作,则可以在 DB facade 中使用 transaction 方法。如果在事务的闭包内抛出异常,事务将会被自动还原。如果闭包运行成功,事务将被自动提交。

你不需要担心在使用 transaction 方法时还需要亲自去手动还原或提交事务:

DB::transaction(function () {
 DB::table('users')->update(['votes' => 1]);

 DB::table('posts')->delete();
});

手动操作事务

如果你想手动处理事务并对还原或提交操作进行完全控制,则可以在 DB facade 使用 beginTransaction 方法:

DB::beginTransaction();

你也可以通过 rollBack 方法来还原事务:

DB::rollBack();

最后,可以通过 commit 方法来提交这个事务:

DB::commit();

注意: DB facade 的事务方法也可以用来控制 查询语句构造器 及 Eloquent ORM 的事务。

示例介绍

假设有要在数据库中存储一个知识点,这个知识点同时属于两个不同的考点,也就是考点和知识点这两个数据是多对多的关系,那么要实现这种数据结构就需要三个表:

知识点表 wiki:

---------------------------------------
id  title    content
---------------------------------------

考点表 tag:

-------------------
id  name
-------------------

考点知识点关联表 wiki_tag_rel

----------------------------------
id   tag_id  wiki_id
----------------------------------

现在要开启事务新增Wiki数据,新增wiki成功后再把它关联到指定的考点上去

(在laravel中使用查询构建器或者Eloquent ORM执行query时,如果失败会返回 Illuminate\Database\QueryException 异常)

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Database\QueryException;
use App\Wiki;

class TestController extends Controller
{
 //用DB facade的事务方法控制 查询语句构建器的事务
 public function storeWiki(Request $request)
 {
  DB::beginTransaction();
  try {
   $tagIds = explode(',', $request->get('tag_id'));
   $wiki_id = DB::table('wiki')->insertGetId([
    'title' => $request->get('title'),
    'content' => $request->get('content')
   ]);

   $relationData = [];
   foreach($tagIds as $tagId) {
    $data = ['wiki_id' => $wiki_id, 'tag_id' => $tagId];
    $relationData[] = $data;
   }
   DB::table('wiki_tag_rel')->insert($relationData);
   DB::commit();
  } catch(\Illuminate\Database\QueryException $ex) {
   DB::rollback();
   return \Response::json(['status' => 'error', 'error_msg' => 'Failed, please contact supervisor']);
  }
  
  return \Response::json(['status' => 'ok']);
 }


 //用DB facade的事务方法控制 Eloquent ORM的事务
 public function createWiki(array $data)
 {
  DB::beginTransaction();
  try {
   $tagIds = explode(',', $data['tag_id']);
   $newWiki = Wiki::create([
    'title' => $data['title'],
    'content' => $data['content']
   ]);
   //Wiki和Tag两个Model使用了belongsToMany建立了多对多的关系
   //通过attach方法来附加wiki和tag的关系(写入中间表)
   $newWiki->tags()->attach($tagIds);
   DB::commit();
  } catch(QueryException $ex) {
   DB::rollback();
   return \Response::json(['status' => 'error', 'error_msg' => 'Failed, please contact supervisor']);
  }

  return \Response::json(['status' => 'ok']);
  }

}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
PHP静态新闻列表自动生成代码
Jun 14 PHP
用PHP查询搜索引擎排名位置的代码
Jan 05 PHP
PHP操作数组的一些函数整理介绍
Jul 17 PHP
php中获取远程客户端的真实ip地址的方法
Aug 03 PHP
php数组函数序列之array_search()- 按元素值返回键名
Nov 04 PHP
php的POSIX 函数以及进程测试的深入分析
Jun 03 PHP
如何在php中正确的使用json
Aug 06 PHP
解决CodeIgniter伪静态失效
Jun 09 PHP
PHP中返回引用类型的方法
Apr 03 PHP
PHP中overload与override的区别
Feb 13 PHP
自写的利用PDO对mysql数据库增删改查操作类
Feb 19 PHP
PHP实现微信红包金额拆分试玩的算法示例
Apr 07 PHP
PHP实现实时生成并下载超大数据量的EXCEL文件详解
Oct 23 #PHP
Laravel学习教程之model validation的使用示例
Oct 23 #PHP
laravel实现批量更新多条记录的方法示例
Oct 22 #PHP
利用PHP获取汉字首字母并且分组排序详解
Oct 22 #PHP
Laravel 5.4因特殊字段太长导致migrations报错的解决
Oct 22 #PHP
PHP高效获取远程图片尺寸和大小的实现方法
Oct 20 #PHP
PHP静态延迟绑定和普通静态效率的对比
Oct 20 #PHP
You might like
2020显卡排行榜天梯图 显卡天梯图2020年3月最新版
2020/04/02 数码科技
用php+mysql一个名片库程序
2006/10/09 PHP
PHP爆绝对路径方法收集整理
2012/09/17 PHP
PHP register_shutdown_function函数的深入解析
2013/06/03 PHP
php实现插入数组但不影响原有顺序的方法
2015/03/27 PHP
PHP设计模式之 策略模式Strategy详解【对象行为型】
2020/05/01 PHP
复制本贴标题和地址的js代码
2008/07/01 Javascript
Juqery Html(),append()等方法的Bug解决方法
2010/12/13 Javascript
JQuery为textarea添加maxlength属性并且兼容IE
2013/04/25 Javascript
jquery鼠标滑过提示title具体实现代码
2013/08/06 Javascript
jQuery删除一个元素后淡出效果展示删除过程的方法
2015/03/18 Javascript
js实现简单的省市县三级联动效果实例
2016/02/18 Javascript
AngularJs 60分钟入门基础教程
2016/04/03 Javascript
jQuery 特性操作详解及实例代码
2016/09/29 Javascript
JS正则子匹配实例分析
2016/12/22 Javascript
通俗易懂地解释JS中的闭包
2017/10/23 Javascript
JS同步、异步、延迟加载的方法
2018/05/05 Javascript
jQuery移动端跑马灯抽奖特效升级版(抽奖概率固定)实现方法
2019/01/18 jQuery
JavaScript中import用法总结
2019/01/20 Javascript
vue input输入框关键字筛选检索列表数据展示
2020/10/26 Javascript
javascript将扁平的数据转为树形结构的高效率算法
2020/02/27 Javascript
Python定义函数功能与用法实例详解
2019/04/08 Python
python如何以表格形式打印输出的方法示例
2019/06/21 Python
python 梯度法求解函数极值的实例
2019/07/10 Python
详解Python 字符串相似性的几种度量方法
2019/08/29 Python
python Manager 之dict KeyError问题的解决
2019/12/21 Python
Python调用scp向服务器上传文件示例
2019/12/22 Python
Python爬取365好书中小说代码实例
2020/02/28 Python
Python 实现国产SM3加密算法的示例代码
2020/09/21 Python
请问如下代码执行后a和b的值分别是什么
2016/05/05 面试题
后勤采购员岗位职责
2013/12/19 职场文书
大学生自我评价范文分享
2014/02/21 职场文书
教师个人自我剖析材料
2014/09/29 职场文书
政风行风自查自纠报告
2014/10/21 职场文书
一般纳税人申请报告
2015/05/18 职场文书
MySQL中JOIN连接的基本用法实例
2022/06/05 MySQL