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页面间传递参数实例代码
Jun 05 PHP
PHP has encountered an Access Violation at 7C94BD02解决方法
Aug 24 PHP
PHP5与MySQL数据库操作常用代码 收集
Mar 21 PHP
php cache类代码(php数据缓存类)
Apr 15 PHP
jQuery Mobile + PHP实现文件上传
Dec 12 PHP
php简单分页类实现方法
Feb 26 PHP
判断、添加和删除WordPress置顶文章的相关PHP函数小结
Dec 10 PHP
总结PHP删除字符串最后一个字符的三种方法
Aug 30 PHP
PHP判断用户是否已经登录(跳转到不同页面或者执行不同动作)
Sep 22 PHP
PHP实现微信对账单处理
Oct 01 PHP
php使用event扩展的io复用测试的示例
Oct 20 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
如何使用脚本模仿登陆过程
2006/11/22 PHP
php简单实现sql防注入的方法
2016/04/22 PHP
php自定义函数实现统计中文字符串长度的方法小结
2017/04/15 PHP
php微信开发之图片回复功能
2018/06/14 PHP
PDO::beginTransaction讲解
2019/01/27 PHP
Ajax+PHP实现的模拟进度条功能示例
2019/02/11 PHP
Javascript 解疑
2009/11/11 Javascript
在firefox和Chrome下关闭浏览器窗口无效的解决方法
2014/01/16 Javascript
详解JavaScript中undefined与null的区别
2014/03/29 Javascript
JavaScript中的索引数组、关联数组和静态数组、动态数组讲解
2014/11/08 Javascript
JavaScript中省略元素对数组长度的影响
2016/10/26 Javascript
Angularjs的Controller间通信机制实例分析
2016/11/07 Javascript
jquery删除数组中重复元素
2016/12/05 Javascript
JS实现的tab切换选项卡效果示例
2017/02/28 Javascript
Vue2.0 给Tab标签页和页面切换过渡添加样式的方法
2018/03/13 Javascript
js中apply和Math.max()函数的问题及区别介绍
2018/03/27 Javascript
微信小程序实现获取用户信息并存入数据库操作示例
2019/05/07 Javascript
了解javascript中的Dom操作
2019/05/27 Javascript
JS造成内存泄漏的几种情况实例分析
2020/03/02 Javascript
[02:00]DAC2018主宣传片——龙征四海,剑问东方
2018/03/20 DOTA
[01:16:13]DOTA2-DPC中国联赛 正赛 SAG vs Dragon BO3 第一场 2月22日
2021/03/11 DOTA
python求素数示例分享
2014/02/16 Python
基于Python实现的微信好友数据分析
2018/02/26 Python
python 获取键盘输入,同时有超时的功能示例
2018/11/13 Python
pyqt5实现登录界面的模板
2020/05/30 Python
python修改文件内容的3种方法详解
2019/11/15 Python
Python手绘可视化工具cutecharts使用实例
2019/12/05 Python
PyCharm 2020.1版安装破解注册码永久激活(激活到2089年)
2020/09/24 Python
HTML5中form如何关闭自动完成功能的方法
2018/07/02 HTML / CSS
HTML5实现签到 功能
2018/10/09 HTML / CSS
和睦家庭事迹
2014/05/14 职场文书
社团活动总结格式
2014/08/29 职场文书
办理信用卡工作证明
2014/09/30 职场文书
工会经费申请报告
2015/05/15 职场文书
《黄道婆》教学反思
2016/02/22 职场文书
nginx rewrite功能使用场景分析
2022/05/30 Servers