PHP開啓事務回滾(TP,全面)

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(); 
 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章