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 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/ya_meidei/article/details/128970882