spring事务的[Transaction rolled back because it has been marked as rollback-only]浅析

有时候在使用事务的时,做了事务嵌套,结果其中有一个抛出异常时,异常会一直连续跑出到最外层。

问题:明明捕获了异常为什么还会抛出。

	@Transactional //第一层 会在方法执行完成后,在进行提交。此时代码已经失去了try-catch保护
	public UserReply queryUser(UserQuery query)
	{
		BaseAccountExt user = null;
		try
		{
                        // 第二层。在此方法中也配置有事务,且抛出异常。它的异常会传递给当前方法
			user = accountService.query(query.getAppCode());
		}
		catch(Exception ex)  // 捕获异常
		{
			ex.printStackTrace();
		}
	
		System.out.println("-----------------------分割线-------------------------------");
		return new UserReply(user);
	}

   

    @Transactional
    public BaseAccountExt query(String name){

        // 先更新数据
    	BaseAccount baseAccountExt = new BaseAccount();
    	baseAccountExt.setFullName("abcd");
    	baseAccountExt.setName(baseAccountExt.getName());
    	baseAccountService.update(baseAccountExt);
    	
        throw new RuntimeException("当前对象不为空!");
    }

 

解决办法:网上可能有很多种说法,但是所有的方法都是一种规避.

  •  或者去掉第一层Transactional,在该方法中,只有向下调用和DB交互,则此一层建议不要在追加事务。
  • 让第二层嵌套事务,不要传递异常到外面,改变事务类型,(其实和第一种相似,但是可能会有业务限制)添加方法:propagation=Propagation.REQUIRES_NEW
  • 在第一层外面,在做一层异常捕获,完整的保证事务异常绝对可以被拦截到。
@ExceptionHandler(value = { ApiException.class, BindException.class,
			Exception.class })
	protected ApiReply checkedException(Exception ex) {
		ApiReply reply = new ApiReply(ApiReplyCode.FAILED);
		
		if (ex instanceof TransactionException) {
			reply = new ApiReply(ApiReplyCode.TRANSACTIONEXCEPTION);
		}
		logError(request, reply, ex);
		return reply;
	}
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值