springBoot service 事務註解@Transactional的用法

springBoot使用事物

一:首先確保使用的mysql爲InnoDB支持事務,否則代碼在怎麼改都無法實現事務回滾操作。

場景分析:

1.默認spring事務只在發生未被捕獲的 RuntimeException 時纔回滾。  
2.spring aop  異常捕獲原理:被攔截的方法需顯式拋出異常,並不能經任何處理,這樣aop代理才能捕獲到方法的異常,才能進行回滾,默認情況下aop只捕獲 RuntimeException 的異常,但可以通過配置來捕獲特定的異常並回滾 ,換句話說在service的方法中不使用try catch 或者在catch中最後加上throw new runtimeexcetpion(),這樣程序異常時才能被aop捕獲進而回滾。

事務寫法分爲三種:

1.手動回滾。給註解加上參數如:@Transactional(rollbackFor=Exception.class)。

2.MyException改爲繼承RuntimeException的異常。並且在service上層要繼續捕獲這個異常並處理。

3.在service層方法的catch語句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();語句,手動回滾,這樣上層就無需去處理異常。

代碼實例參考:

    @Transactional
    @Override
    public double rewareVideoGifts(VideoGiftsParam videoGiftsParam) {
        try {
            Gifts gifts=giftMapper.selGiftsInfo(videoGiftsParam.getGiftsId());
            videoGiftsParam.setGifts_price(gifts.getGifts_price());
            //計算花費總金幣數
            videoGiftsParam.setTotal_gold(gifts.getGifts_price()*((double)videoGiftsParam.getAmount()));
            Live_app_user_info live_app_user_info=giftMapper.seluserInfo(videoGiftsParam.getUserId());
            live_app_user_info.setUser_package(live_app_user_info.getUser_package()-videoGiftsParam.getTotal_gold());
            //扣除用戶金幣
            int result=giftMapper.updateUserGolds(live_app_user_info);
            Video_gifts video_gifts=giftMapper.selVideoGifts(videoGiftsParam);
            if(video_gifts!=null) {
                //累加禮物數量和總金額
                giftMapper.updateVideoGiftsAmount(videoGiftsParam);
            }else {
                //新增禮物
                giftMapper.insVideoGifts(videoGiftsParam);
            }
            //獲取用戶的利潤分成
            double profit=giftMapper.selUserProfit(videoGiftsParam.getVideoUserId());
            videoGiftsParam.setUser_score(videoGiftsParam.getTotal_gold()*profit);
            //用戶積分增加
            Live_app_user_info live_app_user_info2=giftMapper.seluserInfo(videoGiftsParam.getVideoUserId());
            live_app_user_info2.setUser_score(live_app_user_info2.getUser_score()+videoGiftsParam.getUser_score());
            int resultset=giftMapper.updateUserScore(live_app_user_info2);
            
            if(result<=0 || resultset<=0) {
                //事務回滾
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return -1;
            }
            
            //返回用戶剩餘金幣
            return live_app_user_info.getUser_package();
        } catch (Exception e) {
            //事務回滾
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return -1;
        }
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章