PHP开启事务回滚(TP,全面)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_42154707/article/details/86511655

1.没有建立Model的情况下:

a.自动处理回滚:

Db::transaction(function(){
    Db::table('ns_admin')->delete(1);
});

b.手动操作事务:

// 启动事务
Db::startTrans();
try{
    Db::table('ns_admin')->delete(1);
    // 提交事务
    Db::commit();    
} catch (\Exception $e) {
    // 回滚事务
    Db::rollback();
}

 实列:

public function cardPlan(){
        //0未执行,1已执行
        $rew = Db::table('ns_state')->where('id',1)->value('state');
        if($rew == 0){
            //购买月卡,年卡
            $card = Db::table('ns_member')->where(['card_frequency'=>['>',0]])->select();
            //开启事务
            Db::startTrans();
            try{
            for($i=0;$i<count($card);$i++){
                //卡次数减一
                Db::table('ns_member')->where('uid',$card[$i]['uid'])->setDec('card_frequency');
                //修改积分余额
                $account = Db::table('ns_member_account')->where('uid',$card[$i]['uid'])->find();
                $date = [];
                $date['balance'] = $account['goods_point'] + $account['balance'];
                $date['goods_point'] = 0;
                Db::table('ns_member_account')->where('uid',$card[$i]['uid'])->setField($date);
                //添加记录
                if($account['goods_point'] > 0 ){
                    //积分记录
                    $data = [];
                    $data['uid'] = $account['uid'];
                    $data['account_type'] = 4;//4是冻结积分
                    $data['sign'] = 0;
                    $data['number'] = '-'.$account['goods_point'];
                    $data['from_type'] = 40;
                    $data['text'] = '转出'.$account['goods_point'].'冻结积分到余额';
                    $data['create_time'] = time();
                    Db::table('ns_member_account_records')->insert($data);
                    //余额记录
                    $date = [];
                    $date['uid'] = $account['uid'];
                    $date['account_type'] = 2;//2是余额
                    $date['sign'] = 1;
                    $date['number'] = $account['goods_point'];
                    $date['from_type'] = 40;
                    $date['text'] = '转入'.$account['goods_point'].'冻结积分到余额';
                    $date['create_time'] = time();
                    Db::table('ns_member_account_records')->insert($date);
                }
            }
            //未购买
            $card = Db::table('ns_member')->where(['card_frequency'=>0])->select();
            for($i=0;$i<count($card);$i++){
                //修改积分
                $account = Db::table('ns_member_account')->where('uid',$card[$i]['uid'])->find();
                $date = [];
                $date['goods_point'] = 0;
                Db::table('ns_member_account')->where('uid',$card[$i]['uid'])->setField($date);
                //添加记录
                if($account['goods_point'] > 0 ){
                    $data = [];
                    $data['uid'] = $account['uid'];
                    $data['account_type'] = 4;//4是冻结积分
                    $data['sign'] = 0;
                    $data['number'] = '-'.$account['goods_point'];
                    $data['from_type'] = 40;
                    $data['text'] = '未购买月卡或年卡,消除'.$account['goods_point'].'冻结积分';
                    $data['create_time'] = time();
                    Db::table('ns_member_account_records')->insert($data);
                }
            }
            $state = [];
            $state['state'] = 1;
            $state['time'] = time();
            Db::table('ns_state')->where('id',1)->setField($state);
                // 提交事务
                Db::commit();
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
            }
        }
    }

注意:1:在没有model的情况下,在能用Db类的情况里,可以用Db加双冒号开启 ,关闭事务。

           2:一个方法只能开启一个完整事务,开启多个会出错。

2.建有Model的情况下:

public function unionPartnerReward()
    {
        $ns_member = new NsMemberModel();
        $ns_member_account =new NsMemberAccountModel();
        $ns_member_account_records = new NsMemberAccountRecordsModel();

        //获取当前时间 开始时间 和结束时间
        // 防止重复发放。
        $dateStr = date('Y-m-d', time());
        $timestamp0 = strtotime($dateStr);
        $timestamp24 = strtotime($dateStr) + 86400 - 1;
        $reward_where['create_time'] = array('between',[$timestamp0,$timestamp24]);
        $reward_where['from_type'] = 33;
        $reward_where['account_type'] = 2;
        $reward_msg =  $ns_member_account_records->where($reward_where)->limit('0,1')->select();
        if($reward_msg){
            return;
        }
        //股东信息
        $condition['agent_level'] = 4;
        $unionPartnerList = $ns_member->getQuery($condition, "uid", "");
        //加权分红配置
        $config = new ConfigModel();
        $other_set = $config->getInfo(['key'=>'OTHER_SET'],'value');
        $other_set = json_decode($other_set['value'],true);
        $money = $other_set[1]['value_num'];

        //累计消费盒数
        $all_num = $ns_member_account->sum('goods_num');

        $count = count($unionPartnerList);
        $all_money =  $all_num * $money; //今日累计加权值

        if($count>0){
            //平均每位股东分红金额
            $avg_money = sprintf("%.2f",$all_money/$count);
        }
        $time = time();
        $partner_reward = array();
        $ns_member_account->startTrans();//开启事务
        try{
            if(isset($avg_money) && $avg_money>0){
                foreach ($unionPartnerList as $k => $v) {
                    $partner_reward[$k]['uid'] = $v['uid'];
                    $partner_reward[$k]['shop_id'] = 0;
                    $partner_reward[$k]['account_type'] = 2;
                    $partner_reward[$k]['sign'] = 1;
                    $partner_reward[$k]['number'] = $avg_money;
                    $partner_reward[$k]['from_type'] = 33; //加权分红奖励
                    $partner_reward[$k]['data_id'] = 0;
                    $partner_reward[$k]['text'] = '加权分红奖励';
                    $partner_reward[$k]['create_time'] = $time;

                    $ns_member_account->where(['uid'=>$v['uid']])->setInc('balance',$avg_money);
                }
                $ns_member_account_records->saveAll($partner_reward);
            }
            $ns_member_account->commit();
        }catch (\Exception $e){
            $ns_member_account->rollback();
        }
    }

注意:在建有model的时候,可以 new model(名),直接指向来开启,关闭事务回滚!

//事务回滚:
  $model=M('myself_audio');
//事务开启
  $model->startTrans();
  $list=$model->where('id',$id)->delete();
  if(!$list){
    //事务回滚
    $model->rollback();
  }
  $id = M('thumb')->field("id")->where('d'.$id)->select();
  foreach ($id as $val=>$vl){
    $ids[]=$vl['id'];
  }
  $idd=implode(",",$ids);
  $where['id']=array("in",$idd);
  $lists = M('thumb')->where($where)->delete();
  if(!$lists){
    //事务回滚
    $model->rollback();
  }
  //事务提交
  $model->commit();

3.有model,不用try,也可以用if,else:

//  在User模型中启动事务
$User->startTrans();
 // 进行相关的业务逻辑操作
$Info = M("Info"); // 实例化Info对象
$Info->save($User); // 保存用户信息
 if (操作成功){
    // 提交事务
    $User->commit(); 
 }else{
   // 事务回滚
   $User->rollback(); 
 }

猜你喜欢

转载自blog.csdn.net/qq_42154707/article/details/86511655