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 相关文章推荐
我的论坛源代码(七)
Oct 09 PHP
php 静态变量与自定义常量的使用方法
Jan 26 PHP
php产生随机数的两种方法实例代码 输出随机IP
Apr 08 PHP
适用于php-5.2 的 php.ini 中文版[金步国翻译]
Apr 17 PHP
基于curl数据采集之单页面采集函数get_html的使用
Apr 28 PHP
PHP函数microtime()用法与说明
Dec 04 PHP
PHP将两个关联数组合并函数提高函数效率
Mar 18 PHP
Session的工作机制详解和安全性问题(PHP实例讲解)
Apr 10 PHP
php实现的mongodb操作类
May 28 PHP
PHP中explode函数和split函数的区别小结
Aug 24 PHP
php输出图像的方法实例分析
Feb 16 PHP
PHP中危险的file_put_contents函数详解
Nov 04 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
php程序之die调试法 快速解决错误
2009/09/17 PHP
PHP PDOStatement:bindParam插入数据错误问题分析
2013/11/13 PHP
php实现mysql数据库操作类分享
2014/02/14 PHP
PHP统计数值数组中出现频率最多的10个数字的方法
2015/04/20 PHP
jQuery图片的展开和收缩实现代码
2013/04/16 Javascript
JQuery操作单选按钮以及复选按钮示例
2013/09/23 Javascript
JavaScript AOP编程实例
2015/06/16 Javascript
AngularJS基础 ng-cut 指令介绍及简单示例
2016/08/01 Javascript
深入浅出ES6之let和const命令
2016/08/25 Javascript
JavaScript中Array对象用法实例总结
2016/11/29 Javascript
Vue中定义全局变量与常量的各种方式详解
2017/08/23 Javascript
React/Redux应用使用Async/Await的方法
2017/11/16 Javascript
Vue 按键修饰符处理事件的方法
2018/05/04 Javascript
JS获取今天是本月第几周、本月共几周、本月有多少天、是今年的第几周、是今年的第几天的示例代码
2018/12/05 Javascript
vue 集成 vis-network 实现网络拓扑图的方法
2019/08/07 Javascript
python实现的阳历转阴历(农历)算法
2014/04/25 Python
解决windows下Sublime Text 2 运行 PyQt 不显示的方法分享
2014/06/18 Python
Python自动化运维和部署项目工具Fabric使用实例
2016/09/18 Python
python将秒数转化为时间格式的实例
2018/09/16 Python
解决Pycharm运行时找不到文件的问题
2018/10/29 Python
Python 保存矩阵为Excel的实现方法
2019/01/28 Python
基于python分析你的上网行为 看看你平时上网都在干嘛
2019/08/13 Python
Python协程操作之gevent(yield阻塞,greenlet),协程实现多任务(有规律的交替协作执行)用法详解
2019/10/14 Python
Python3.7+tkinter实现查询界面功能
2019/12/24 Python
Python批量删除mysql中千万级大量数据的脚本分享
2020/12/03 Python
长青弘远的面试题
2012/06/09 面试题
网站编辑求职信
2013/10/17 职场文书
建筑工程自我鉴定
2013/10/18 职场文书
晚会邀请函范文
2014/01/24 职场文书
给老婆的婚前保证书
2014/02/01 职场文书
幼儿发展评估方案
2014/06/11 职场文书
王金山在党的群众路线教育实践活动总结大会上的讲话稿
2014/10/25 职场文书
课外活动实习计划
2015/01/19 职场文书
思想道德自我评价2015
2015/03/09 职场文书
银行中层干部培训心得体会
2016/01/11 职场文书
Python实现对齐打印 format函数的用法
2022/04/28 Python