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;
}
}