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