1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > spring事务失效二:业务代码捕获异常

spring事务失效二:业务代码捕获异常

时间:2021-03-14 10:42:54

相关推荐

spring事务失效二:业务代码捕获异常

对于我们在使用事务的时候,如果我们自己的业务代码中,通过try catch去捕获了异常,那此时原本应该回滚的事务是无法进行回滚的,这个spring事务底层的处理逻辑有关系

应用

代码就不贴了,给各截图,偷个懒

如果这个代码去执行的时候,是没有问题的,事务会进行回滚,但是假如我们其中的一个或者两个try catch都打开之后,就会出现,原本应该回滚的事务,却不回滚了,这是在事务拦截器执行的时候,会对业务代码进行异常捕获,假如我们自己捕获了异常,事务拦截器就无法拦截到异常

为什么不回滚

为什么不回滚,是和spring事务底层的代码有关系,至于spring事务是如何生成代理对象的,如何被拦截的,就不说了,在前面的笔记中有说过,我们来看,spring事务拦截到之后,所执行的代码

org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransactionprotected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,final InvocationCallback invocation) throws Throwable {// If the transaction attribute is null, the method is non-transactional.TransactionAttributeSource tas = getTransactionAttributeSource();final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);final TransactionManager tm = determineTransactionManager(txAttr);PlatformTransactionManager ptm = asPlatformTransactionManager(tm);final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {// 1.根据当前是否存在事务,和不同的传播机制,去判断是要挂起事务,还是生成新的事务等TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);Object retVal;try {// 2.这是去执行目标方法retVal = invocation.proceedWithInvocation();}catch (Throwable ex) {// 3.在目标方法抛出异常时,判断是否需要进行回滚completeTransactionAfterThrowing(txInfo, ex);throw ex;}finally {// 4.清理事务信息,恢复挂起的事务cleanupTransactionInfo(txInfo);}if (vavrPresent && VavrDelegate.isVavrTry(retVal)) {// Set rollback-only in case of Vavr failure matching our rollback rules...TransactionStatus status = txInfo.getTransactionStatus();if (status != null && txAttr != null) {retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);}}commitTransactionAfterReturning(txInfo);return retVal;}}

这是目标方法被拦截之后,执行的部分代码,也是这个问题的核心,我们可以看到,对于异常回滚的处理,是在try catch里面去处理的,也就是说,如果我们自己在业务代码中,去捕获了异常,那也意味着,在这里是无法执行到catch里面的逻辑,所以,会进行事务得提交,那这样肯定是有问题的,所以,在实际业务代码中,一定要注意,如果加了事务注解,那一定不要在代码中取捕获异常,如果说想要把异常处理的更为通用或者规范,那可以在捕获到异常之后,对异常记录或者处理之后,再抛出一个异常,这样,才能被事务的拦截器捕获到,然后进行回滚的操作,要不然,事务就失去了其意义

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。