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

 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 }

 

 

 
 
 
 

 

 

 

转载于:https://www.cnblogs.com/Renyi-Fan/p/9527985.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值