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 google或baidu分页代码
Nov 26 PHP
php快速url重写 更新版[需php 5.30以上]
Apr 20 PHP
php设计模式 Singleton(单例模式)
Jun 26 PHP
基于php上传图片重命名的6种解决方法的详细介绍
Apr 28 PHP
PHP中数组定义的几种方法
Sep 01 PHP
php实现cc攻击防御和防止快速刷新页面示例
Feb 13 PHP
php中session与cookie的比较
Jan 27 PHP
php通过strpos查找字符串出现位置的方法
Mar 17 PHP
PHP数据库表操作的封装类及用法实例详解
Jul 12 PHP
Apache PHP MySql安装配置图文教程
Aug 27 PHP
验证坐标在某坐标区域内php代码
Oct 08 PHP
php用xpath解析html的代码实例讲解
Feb 14 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
如何在WIN2K下安装PHP4.04
2006/10/09 PHP
PHP新手上路(二)
2006/10/09 PHP
PHP iconv 函数转gb2312的bug解决方法
2009/10/11 PHP
php在多维数组中根据键名快速查询其父键以及父键值的代码
2011/05/07 PHP
redis 队列操作的例子(php)
2012/04/12 PHP
windows7下php开发环境搭建图文教程
2015/01/06 PHP
php获取给定日期相差天数的方法分析
2017/02/20 PHP
Laravel框架搜索分页功能示例
2019/02/01 PHP
统计PHP目录中的文件数方法
2019/03/05 PHP
js中将HTMLCollection/NodeList/伪数组转换成数组的代码
2011/07/31 Javascript
js中单引号与双引号冲突问题解决方法
2013/10/04 Javascript
jquery $(&quot;#variable&quot;) 循环改变variable的值示例
2014/02/23 Javascript
我的Node.js学习之路(四)--单元测试
2014/07/06 Javascript
常用的JavaScript模板引擎介绍
2015/02/28 Javascript
关于input全选反选恶心的异常情况
2016/07/24 Javascript
JS制作图形验证码实现代码
2020/10/19 Javascript
JavaScript反射与依赖注入实例详解
2018/05/29 Javascript
如何用JavaScript实现功能齐全的单链表详解
2019/02/11 Javascript
详解微信小程序用定时器实现倒计时效果
2019/04/30 Javascript
微信小程序实现折线图的示例代码
2019/06/07 Javascript
Python实现选择排序
2017/06/04 Python
Python实现的科学计算器功能示例
2017/08/04 Python
对python多线程与global变量详解
2018/11/09 Python
Python GUI编程 文本弹窗的实例
2019/06/11 Python
用Python从0开始实现一个中文拼音输入法的思路详解
2019/07/20 Python
利用ImageAI库只需几行python代码实现目标检测
2019/08/09 Python
Flask框架学习笔记之模板操作实例详解
2019/08/15 Python
CSS3实现文本垂直排列的方法
2018/07/10 HTML / CSS
压铸汽车模型收藏家:Diecastmodelswholesale.com
2016/12/21 全球购物
奢华时尚的独特视角:La Garçonne
2018/06/07 全球购物
国贸专业个人求职信范文
2014/01/08 职场文书
服装设计专业求职信
2014/06/16 职场文书
2015年端午节活动策划书
2015/05/05 职场文书
2015年小学数学教师工作总结
2015/05/20 职场文书
一波干货,会议主持词开场白范文
2019/05/06 职场文书
Go语言基础函数基本用法及示例详解
2021/11/17 Golang