Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 834|回复: 0

thinkphp事务处理以及无效时的解决方案(整理)

[复制链接]
  • TA的每日心情
    奋斗
    7 天前
  • 签到天数: 803 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726482
    发表于 2021-5-10 12:23:00 | 显示全部楼层 |阅读模式

    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之中

     1     $trans_result = true;
     2     $trans = M();
     3     $trans->startTrans();   // 开启事务
     4 
     5     try {   // 异常处理
     6         // 更新实施
     7         $busbidList = M("busbid")->where($map)->select();
     8         foreach($busbidList as $k => $v) {
     9             $map['id'] = $busbidList[$k]['id'];
    10             $result = M('busbid')->where($map)->data($data)->save();
    11             if ($result === false) {
    12                 throw new Exception(“错误原因”);
    13             }
    14         }
    15     } catch (Exception $ex) {
    16         $trans_result = false;
    17         // 记录日志
    18         Log::record("== xxx更新失败 ==", 'DEBUG');
    19         Log::record($ex->getMessage(), 'DEBUG');
    20     }
    21 
    22     if ($trans_result === false) {
    23         $trans->rollback();
    24         // 更新失败
    25         $array['status'] = 0;
    26     } else {
    27         $trans->commit();
    28         // 更新成功
    29         $array['status'] = 1;
    30     }

     

     

    五、数据表修改储存引擎位置

    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 }

     

     

     
     
     
     

     

     

     
    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-11-24 12:46 , Processed in 0.169854 second(s), 27 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表