thinkphp事务处理以及无效时的解决方案(整理)
thinkphp事务处理以及无效时的解决方案(整理)
一、总结
一句话总结:要程序里面支持事务,首先连接的数据库和数据表必须支持事务 mysql
1、InnoDB和MyISAM对事务的支持怎么样?
InnoDB支持事务
MyISAM不支持事务
2、thinkphp中事务无效如何解决?
可以首先尝试将数据表存储引擎改为:InnoDB
3、在哪里修改数据表的存储引擎?
design table->Options
二、thinkphp 的事务回滚处理 和 原始PHP的事务回滚实例
1、要程序里面支持事务,首先连接的数据库和数据表必须支持事务 mysql 为例:
数据库InnoDB支持 transactions

数据表支持事务:InnoDB 支持transaction

2、框架thinkphp 支持事务代码
public function testrollback(){
$model1 = D('item');
$model2 = D('vote');
$model1->startTrans();
$res1 = $model1->where('id = 5')->delete();
$res2 = $model2->where('id = 2')->delete();
dump($res1);
dump($res2);
if($res1 && $res2){
$model1->commit(); //只有$res1 和 $res2 都执行成功是才真正执行上面的数据库操作
dump("commit");
}else{
$model1->rollback(); // 条件不满足,回滚
dump("rollback");
}
dump("over");
exit;
}
3、原始PHP 代码事务实例
方法一:只支持数据库和数据表都是 innoDB 的情况
public function rollbackoriginal1(){
$conn = mysql_connect('127.0.0.1','summerzi','summerzi') or die('DB connection failed!');
mysql_select_db('summer',$conn);
mysql_query('set names "GBK"');
mysql_query('BEGIN');
$sql1 = "INSERT INTO `summer_userdata`(`uid`,`type`,`target_id`) VALUES(41,1,233);";
$sql2 = "INSERT INTO `summer_userdata`(`uid`,`type`,`target_id`) VALUES(fdfd,2,235);";
$res1 = mysql_query($sql1);
$res2 = mysql_query($sql2);
dump($sql1);
dump($sql2);
dump($res1);
dump($res2);
if($res1 && $res2){
mysql_query('COMMIT');
dump('commit success!');
}else{
mysql_query('ROLLBACK');
dump('commit failed, rollback!');
}
mysql_query('END');
}
方法二:(注意:对于不支持事务的MyISAM引擎数据库可以使用表锁定的方法)
public function rollbackoriginal2(){
$conn = mysql_connect('127.0.0.1','summerzi','summerzi') or die('DB connection failed!');
mysql_select_db('summer',$conn);
mysql_query('set names "GBK"');
mysql_query('SET AUTOCOMMIT=0');////设置mysql不自动提交,需自行用commit语句提交
$sql1 = "INSERT INTO `summer_userdata`(`uid`,`type`,`target_id`) VALUES(41,1,233);";
$sql2 = "INSERT INTO `summer_userdata`(`uid`,`type`,`target_id`) VALUES(44,2,235);";
//mysql_query("LOCK TABLES `hmbl_userdata` WRITE");//锁定表
$res1 = mysql_query($sql1);
$res2 = mysql_query($sql2);
dump($sql1);
dump($sql2);
dump($res1);
dump($res2);
//mysql_query("UNLOCK TABLES");//解除锁定
if($res1 && $res2){
mysql_query('COMMIT');
dump('commit success!');
}else{
mysql_query('ROLLBACK');
dump('commit failed, rollback!');
}
mysql_query("SET AUTOCOMMIT=1");
mysql_query('END');
}
php + mysql 对事务的处理比较简单,涉及到业务中多个数据操作,就可以考虑用事务处理
参考:thinkphp 的事务回滚处理 和 原始PHP的事务回滚实例 - summerzi - 博客园
https://www.cnblogs.com/summerzi/archive/2015/04/05/4393790.html
三、thinkphp事务处理无效时的解决办法,一击命中!
处理事务的时候,发现没有办法rollback,找了好久,我终于发现了问题所在:
以下干货:
数据表存储引擎改为:InnoDB
参考:thinkphp事务处理无效时的解决办法,一击命中! - CSDN博客
https://blog.csdn.net/yhq1988923/article/details/53516830
四、ThinkPHP 事务处理 (事务回滚) 、异常处理代码
事务代码写在try-catch之中
$trans_result = true;
$trans = M();
$trans->startTrans(); // 开启事务 try { // 异常处理
// 更新实施
$busbidList = M("busbid")->where($map)->select();
foreach($busbidList as $k => $v) {
$map['id'] = $busbidList[$k]['id'];
$result = M('busbid')->where($map)->data($data)->save();
if ($result === false) {
throw new Exception(“错误原因”);
}
}
} catch (Exception $ex) {
$trans_result = false;
// 记录日志
Log::record("== xxx更新失败 ==", 'DEBUG');
Log::record($ex->getMessage(), 'DEBUG');
} if ($trans_result === false) {
$trans->rollback();
// 更新失败
$array['status'] = 0;
} else {
$trans->commit();
// 更新成功
$array['status'] = 1;
}
五、数据表修改储存引擎位置
design table->Options

六、thinkphp事务中if($ans1&&$ans2){}else{}方式和try{}catch{}方式事务操作的区别在哪里?
if_else方式是两个都要影响了数据库才能执行
try_catch方式是只要不发生异常就执行。
比如数据表中有id为12345的字段
比如说我们现在删除id为5和6的字段
在if_else中就是rollback,
在try_catch中就是commit
1 //19、测试事务操作
2 public function test18(){
3 Db::startTrans();
4 $ans1=db('myself_goods')->delete(6);
5 $ans2=db('myself_goods')->delete(5);
6 if($ans1&&$ans2){
7 // 提交事务
8 dump('commit');
9 Db::commit();
10 }else{
11 // 回滚事务
12 Db::rollback();
13 dump('rollback');
14 }
15 }
16
17 //18、测试事务操作
18 public function test17(){
19 // 启动事务
20 Db::startTrans();
21 try{
22 $ans1=db('myself_goods')->delete(6);
23 $ans2=db('myself_goods')->delete(7);
24 dump('$ans1: '.$ans1);
25 dump('$ans2: '.$ans2);
26 // 提交事务
27 dump('commit');
28 Db::commit();
29 } catch (\Exception $e) {
30 // 回滚事务
31 Db::rollback();
32 dump('rollback');
33 }
34 }
thinkphp事务处理以及无效时的解决方案(整理)的更多相关文章
- Android RecyclerView遇到notifyDataSetChanged无效时的解决方案
一.简述 不管AbsListView(ListView.GridView)或是新出的RecyclerView,在使用notifyDataSetChanged方法更新列表数据时,一定要保证数据为同个对象 ...
- 当target属性在XHTML script中无效时
<a href="#" target=_blank></a>target此属性能够使链接在新窗口打开,但是在XHTML script中无效时. 那么解决方案 ...
- Qt之高DPI显示器(一) - 解决方案整理
目录 DPI发展 1.PPI 2.DPI 一.Win自适应系统 二.Qt机制 1.Windows系统DWM缩放 2. Qt适配高DPI 3.适配DPI结论 三.Qt适配 四.自己适配 1.窗口大小 2 ...
- DataGridView 行数据验证:当输入数据无效时不出现红色感叹号的Bug
private void dgvView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e){ if ...
- python解释器的安装;python2与python3同时在环境变量中时的解决方案
新文档 html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,addres ...
- C#调试含有源代码的动态链接库遇见there is no source code available for the current location提示时的解决方案
C#调试含有源代码的动态链接库遇见there is no source code available for the current location提示时的解决方案: 1.首先试最常规的方法:Cle ...
- IDE按住ctrl 打开单元 无效时 的方法
一般打开单元无效时 是由于程序有错误,若程序没有错误 可以重新build一下 再试. 若实在不行 就右键---open at cursor
- Android 开发时使用 ViewPager 的问题及解决方案整理
1. ViewPager 的页面重置问题 当我们使用ViewPager控件时,假设我们的ViewPager有三页,当我们第一次启动ViewPager显示第一页的时候,ViewPager会预加载第二页, ...
- Base-64 字符数组或字符串的长度无效等问题解决方案
项目特殊需要,调用ActiveX三维控件进行控件某一特殊部位的截图操作,这个截图保存由ActiveX控件控制保存到本地是没问题的,现在需要将这个截图上传到服务器,多人共享,就牵扯到需要读取本地文件…… ...
随机推荐
- SCU 1095运送物资(最短路)
SCU 1095运送物资(最短路) X国发生了内战.起义军得到了广大人民的支持.在一次战役中,反动军队结集了大量兵力,围攻起义军的主堡W城.为支援前线,后方各个供给基地城市纷纷准备将物资运往W城.各基 ...
- 计数排序、桶排序python实现
计数排序在输入n个0到k之间的整数时,时间复杂度最好情况下为O(n+k),最坏情况下为O(n+k),平均情况为O(n+k),空间复杂度为O(n+k),计数排序是稳定的排序. 桶排序在输入N个数据有M个 ...
- Understanding IIS Bindings, Websites, Virtual Directories, and lastly Application Pools
In a recent meeting, some folks on my team needed some guidance on load testing the Web application ...
- c# 读取导入的excel文件,循环批量处理数据
dt = FM_HR_ShiftMaintenanceManager.GetCsvToDataTable(strConn, excelName,"XJSQMonthlyImportExcel ...
- Codefroces 852 G. Bathroom terminal
G. Bathroom terminal Smith wakes up at the side of a dirty, disused bathroom, his ankle chained to p ...
- UVA And Then There Was One
约瑟夫环问题,只不过每次删除一个后,在移m的倍数. #include <iostream> #include <cstdio> #include <cstring> ...
- modelForm所遇问题
1. 通过modelForm创建表单所遇问题 id 在modelForm中无法创建使用 因为它是django的设置,自增的字段,而不是模型中所设置的字段. 当关联外键时,创建多选的下拉框时,需要注意此 ...
- Expression表达式树(C#)
Lambda表达式: 1.下面举例通过Lambda表达式创建了一个用于验证Name的Func委托. //通过Lambda表达式创建一个对象的Name属性验证委托 Func<SearchInfo, ...
- OpenCASCADE 参数曲面面积
OpenCASCADE 参数曲面面积 eryar@163.com Abstract. 本文介绍了参数曲面的第一基本公式,并应用曲面的第一基本公式,结合OpenCASCADE中计算多重积分的类,对任意参 ...
- Android实现本地图片选择及预览缩放效果仿春雨医生
在做项目时常常会遇到选择本地图片的需求.曾经都是懒得写直接调用系统方法来选择图片.可是这样并不能实现多选效果.近期又遇到了,所以还是写一个demo好了.以后也方便使用.还是首先来看看效果 显示的图片使 ...