setRollbackOnly只是作为一个标记在方法结束后才会真正的去做回滚,而不是立马做回滚
@Transactional(rollbackFor = Exception.class)
public Map<String, Object> MtrlExport(Map<String, Object> request) {
Map<String, Object> result = null;
try {
result = executeMtrlExport(request);
mtrlUtils.insertLog(request, "4", result,"");
} catch (Exception e1) {
LOGGER.error("接口异常",e1);
//回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
mtrlUtils.insertLog(request, "4", result,e1.getMessage());
return ResultUtils.buildResult(Constants.FAILURE, "项目出现未知异常,请联系处理!");
}
return result;
}
此时如果executeMtrlExport方法发生异常,日志的插入也会被回滚
解决方法:
可以设置插入日志的方法的事务传播特性为 REQUIRES_NEW
@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
public void insertLog(Map request,String logType,Map logReturn,String error) {
String serialNo= (String) request.get("serial_no");
String logParam=com.alibaba.fastjson.JSON.toJSONString(request);
String logreturn= "".equals(error) ?JSON.toJSONString(logReturn):error;
utilsDao.insertMtrlChargeLog(serialNo, logType, logParam, logreturn);
}
Spring事务传播的七种方式:
1.REQUIRE
Propagation.REQUIRED:如果当前存在事务,那么就加入这个事务,不存在就新建一个事务。
2.SUPPORTS
Propagation.SUPPORTS:如果当前有事务,加入事务,如果没有则不使用事务
3.NOT_SUPPORTED
NOT_SUPPORTED:表示不支持事务,如果有事务也不加入事务,没有事务以非事务运行
4.REQUIRES_NEW
REQUIRES_NEW:不管是否存在事务,都以最新的事务执行,执行完在执行旧的事务
5.MANDATORY
MANDATORY(强制的):必须在一个事务中执行,如果没有事务,则抛出异常
6.NEVER
NEVER:以非事务的方式执行,如果存在事务异常
7.PROPAGATION_NESTED
PROPAGATION_NESTED:如果调用者不存在事务,那么被调用者自己创建事务,这种情况和REQUIRE一样。如果调用者存在事务,那么被调用者就在调用者的事务里嵌套一个事务,称为嵌套事务。
使用嵌套事务是用条件的:
数据库的支持
JDK 1.4 才支持 java.sql.Savepoint 。所以JDK必须在1.4 及以上
还需要Spring中配置nestedTransactionAllowed=true
版权声明:本文为ya_meidei原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。