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函数)
Oct 09 PHP
php 无限极分类
Mar 27 PHP
PHP 执行系统外部命令 system() exec() passthru()
Aug 11 PHP
Linux下将excel数据导入到mssql数据库中的方法
Feb 08 PHP
PHP 导出数据到淘宝助手CSV的方法分享
Feb 27 PHP
php更改目录及子目录下所有的文件后缀的代码
Sep 24 PHP
基于php伪静态的实现详细介绍
Apr 28 PHP
解析如何屏蔽php中的phpinfo()函数
Jun 06 PHP
PHP使用token防止表单重复提交的方法
Apr 07 PHP
PHP封装的MSSql操作类完整实例
May 26 PHP
laravel配置Redis多个库的实现方法
Apr 10 PHP
php中使用array_filter()函数过滤数组实例讲解
Mar 03 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
从网上搜到的phpwind 0day的代码
2006/12/07 PHP
snoopy PHP版的网络客户端提供本地下载
2008/04/15 PHP
谈谈新手如何学习PHP 默默经典版本
2009/08/04 PHP
利用curl 多线程 模拟 并发的详解
2013/06/14 PHP
php中怎么搜索相关联数组键值及获取之
2013/10/17 PHP
php判断正常访问和外部访问的示例
2014/02/10 PHP
php使用反射插入对象示例分享
2014/03/11 PHP
验证坐标在某坐标区域内php代码
2016/10/08 PHP
PHP实现文件上传下载实例
2016/10/18 PHP
php和asp语法上的区别总结
2019/05/12 PHP
IE 上下滚动展示模仿Marquee机制
2009/12/20 Javascript
关于捕获用户何时点击window.onbeforeunload的取消事件
2011/03/06 Javascript
jquery中的 $(&quot;#jb51&quot;)与document.getElementById(&quot;jb51&quot;) 的区别
2011/07/26 Javascript
JavaScript加强之自定义callback示例
2013/09/21 Javascript
jQuery复制表单元素附源码分享效果演示
2015/09/30 Javascript
javascript简单实现跟随滚动条漂浮的返回顶部按钮效果
2016/08/19 Javascript
Angular模板表单校验方法详解
2017/08/11 Javascript
详解Webpack + ES6 最新环境搭建与配置
2018/06/04 Javascript
async/await让异步操作同步执行的方法详解
2019/11/01 Javascript
python 生成不重复的随机数的代码
2011/05/15 Python
Python使用设计模式中的责任链模式与迭代器模式的示例
2016/03/02 Python
1 行 Python 代码快速实现 FTP 服务器
2018/01/25 Python
一文了解Python并发编程的工程实现方法
2019/05/31 Python
python 字典操作提取key,value的方法
2019/06/26 Python
详细整理python 字符串(str)与列表(list)以及数组(array)之间的转换方法
2019/08/30 Python
python简单实现9宫格图片实例
2020/09/03 Python
python不同版本的_new_不同点总结
2020/12/09 Python
html5 Canvas画图教程(7)—canvas里画曲线之quadraticCurveTo方法
2013/01/09 HTML / CSS
了解AppleTalk协议吗
2014/04/01 面试题
银行服务感言
2014/03/01 职场文书
车间主任岗位职责
2014/03/16 职场文书
助人为乐模范事迹材料
2014/06/02 职场文书
老干部工作先进事迹
2014/08/17 职场文书
学校光盘行动倡议书
2015/04/28 职场文书
2015年国庆节演讲稿范文
2015/07/30 职场文书
大学迎新生欢迎词
2015/09/29 职场文书