Spring事务失效七个场景
1、数据库引擎不支持事务
2、不支持事务(事务传播开启(propagation = Propagation.NOT_SUPPORTED))
3、方法不是 publi修饰
4、没有被 Spring 管理
5、数据库引擎不支持事务
6、自身调用问题
之前@Transactional加在内部调用方法上,事务失效----重点记录
@Override
public void dataHandler() {
List<StandingAuthorityPO> informedList;
List<StandingAuthorityPO> renewedList;
int informedListSize = 0;
int renewedListSize = 0;
//处理已通知数据
do {
informedList = doInformedData();
informedListSize += informedList.size();
} while (!informedList.isEmpty() && informedList.size() == handlerStep);
//处理已续期数据
do {
renewedList = doRenewedData();
renewedListSize += renewedList.size();
} while (!renewedList.isEmpty() && renewedList.size() == handlerStep);
if (informedListSize > 0) {
String message = String.format("定时任务常设协议授权状态修改结束,用户状态从已通知修改为待续费完成%d单", informedListSize);
log.info(message);
monitorInterface.sendScheduleNormalNotice(message, true);
}
if (renewedListSize > 0) {
String message = String.format("定时任务常设协议授权状态修改结束,用户状态从已续费修改为未到期完成%d单", renewedListSize);
log.info(message);
monitorInterface.sendScheduleNormalNotice(message, true);
}
}
@Transactional
public List<StandingAuthorityPO> doInformedData() {
List<StandingAuthorityPO> list = standingAuthorityDAO.getListByStatusAndNoticeEndDate(StandingAuthorityEnum.Informed.getCode(), getDate(), handlerStep);
list.forEach(standingAuthorityPO -> {
standingAuthorityPO.setStatus(StandingAuthorityEnum.ToBeRenewed.getCode());
standingAuthorityPO.setProcessTime(LocalDateTime.now());
standingAuthorityDAO.updateById(standingAuthorityPO);
saveStandingAuthorityFlow(StandingAuthorityFlowEnum.ToBeRenewed.getCode(), standingAuthorityPO);
});
return list;
}
@Transactional
public List<StandingAuthorityPO> doRenewedData() {
List<StandingAuthorityPO> list = standingAuthorityDAO.getListByStatus(StandingAuthorityEnum.Renewed.getCode(), handlerStep);
list.forEach(standingAuthorityPO -> {
standingAuthorityPO.setStatus(StandingAuthorityEnum.NotExpired.getCode());
standingAuthorityPO.setProcessTime(LocalDateTime.now());
standingAuthorityDAO.updateById(standingAuthorityPO);
saveStandingAuthorityFlow(StandingAuthorityFlowEnum.Finished.getCode(), standingAuthorityPO);
});
return list;
}
@Transactional
public void saveStandingAuthorityFlow(Integer status, StandingAuthorityPO standingAuthorityPO) {
StandingAuthorityFlowPO standingAuthorityFlowPO = new StandingAuthorityFlowPO();
BeanUtil.copyProperties(standingAuthorityPO, standingAuthorityFlowPO);
standingAuthorityFlowPO.setOptType(status);
standingAuthorityFlowDAO.save(standingAuthorityFlowPO);
}
下面是正确使用:
@Override
@Transactional
public void dataHandler() {
List<StandingAuthorityPO> informedList;
List<StandingAuthorityPO> renewedList;
int informedListSize = 0;
int renewedListSize = 0;
//处理已通知数据
do {
informedList = doInformedData();
informedListSize += informedList.size();
} while (!informedList.isEmpty() && informedList.size() == handlerStep);
//处理已续期数据
do {
renewedList = doRenewedData();
renewedListSize += renewedList.size();
} while (!renewedList.isEmpty() && renewedList.size() == handlerStep);
if (informedListSize > 0) {
String message = String.format("定时任务常设协议授权状态修改结束,用户状态从已通知修改为待续费完成%d单", informedListSize);
log.info(message);
monitorInterface.sendScheduleNormalNotice(message, true);
}
if (renewedListSize > 0) {
String message = String.format("定时任务常设协议授权状态修改结束,用户状态从已续费修改为未到期完成%d单", renewedListSize);
log.info(message);
monitorInterface.sendScheduleNormalNotice(message, true);
}
}
public List<StandingAuthorityPO> doInformedData() {
List<StandingAuthorityPO> list = standingAuthorityDAO.getListByStatusAndNoticeEndDate(StandingAuthorityEnum.Informed.getCode(), getDate(), handlerStep);
list.forEach(standingAuthorityPO -> {
standingAuthorityPO.setStatus(StandingAuthorityEnum.ToBeRenewed.getCode());
standingAuthorityPO.setProcessTime(LocalDateTime.now());
standingAuthorityDAO.updateById(standingAuthorityPO);
saveStandingAuthorityFlow(StandingAuthorityFlowEnum.ToBeRenewed.getCode(), standingAuthorityPO);
});
return list;
}
public List<StandingAuthorityPO> doRenewedData() {
List<StandingAuthorityPO> list = standingAuthorityDAO.getListByStatus(StandingAuthorityEnum.Renewed.getCode(), handlerStep);
list.forEach(standingAuthorityPO -> {
standingAuthorityPO.setStatus(StandingAuthorityEnum.NotExpired.getCode());
standingAuthorityPO.setProcessTime(LocalDateTime.now());
standingAuthorityDAO.updateById(standingAuthorityPO);
saveStandingAuthorityFlow(StandingAuthorityFlowEnum.Finished.getCode(), standingAuthorityPO);
});
return list;
}
public void saveStandingAuthorityFlow(Integer status, StandingAuthorityPO standingAuthorityPO) {
StandingAuthorityFlowPO standingAuthorityFlowPO = new StandingAuthorityFlowPO();
BeanUtil.copyProperties(standingAuthorityPO, standingAuthorityFlowPO);
standingAuthorityFlowPO.setOptType(status);
standingAuthorityFlowDAO.save(standingAuthorityFlowPO);
}
7、异常问题
异常问题有两个:
1、异常被吃掉没有抛出异常,事务会失效
2、异常捕捉后抛出非Runtime异常,事务会失效----解决加上@Transactional(rollbackFor = Exception.class)注解