Spring 事务原理
Posted 冬马党
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring 事务原理相关的知识,希望对你有一定的参考价值。
1,从@EnableTransactionManagement 开始入手
2,看到它给容器注册了 TransactionManagementConfigurationSelector 类
3,观察其 selectImports 方法,发现它给容器注册了两个bean
4,分别是 AutoProxyRegistrar 和 ProxyTransactionManagementConfiguration ,这里重点看下 ProxyTransactionManagementConfiguration
5,发现 proxyxxx 给容器注册了 3个bean BeanFactoryTransactionAttributeSourceAdvisor(事务增强器) ,AnnotationTransactionAttributeSource(注解事务属性),TransactionInterceptor(事务拦截器)
6,观察 AnnotationTransactionAttributeSource ,发现它会解析@Transactional 的属性
#SpringTransactionAnnotationParser 类 protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) { RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute(); Propagation propagation = attributes.getEnum("propagation"); rbta.setPropagationBehavior(propagation.value()); Isolation isolation = attributes.getEnum("isolation"); rbta.setIsolationLevel(isolation.value()); rbta.setTimeout(attributes.getNumber("timeout").intValue()); rbta.setReadOnly(attributes.getBoolean("readOnly")); rbta.setQualifier(attributes.getString("value")); ArrayList<RollbackRuleAttribute> rollBackRules = new ArrayList<>(); Class<?>[] rbf = attributes.getClassArray("rollbackFor"); for (Class<?> rbRule : rbf) { RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule); rollBackRules.add(rule); } String[] rbfc = attributes.getStringArray("rollbackForClassName"); for (String rbRule : rbfc) { RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule); rollBackRules.add(rule); } Class<?>[] nrbf = attributes.getClassArray("noRollbackFor"); for (Class<?> rbRule : nrbf) { NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule); rollBackRules.add(rule); } String[] nrbfc = attributes.getStringArray("noRollbackForClassName"); for (String rbRule : nrbfc) { NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule); rollBackRules.add(rule); } rbta.getRollbackRules().addAll(rollBackRules); return rbta; }
7,再看 TransactionInterceptor ,发现它实现了 MethodInterceptor 也就是目标方法被调用的时候,实际执行的是 TransactionInterceptor 的 invoke 方法
8,观察 invoke 方法 ,调用了 invokeWithinTransaction 方法
protected 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 PlatformTransactionManager tm = determineTransactionManager(txAttr); final String joinpointIdentification = methodIdentification(method, targetClass, txAttr); if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) { // Standard transaction demarcation with getTransaction and commit/rollback calls. TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification); Object retVal = null; try { // This is an around advice: Invoke the next interceptor in the chain. // This will normally result in a target object being invoked. //执行目标方法,得到结果 retVal = invocation.proceedWithInvocation(); } catch (Throwable ex) { // target invocation exception //目标方法发生异常,利用事务管理器进行回滚 completeTransactionAfterThrowing(txInfo, ex); throw ex; } finally { //收尾工作 cleanupTransactionInfo(txInfo); } //提交事务,利用事务管理器进行提交 commitTransactionAfterReturning(txInfo); return retVal; } else { final ThrowableHolder throwableHolder = new ThrowableHolder(); // It‘s a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in. try { Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> { TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status); try { return invocation.proceedWithInvocation(); } catch (Throwable ex) { if (txAttr.rollbackOn(ex)) { // A RuntimeException: will lead to a rollback. if (ex instanceof RuntimeException) { throw (RuntimeException) ex; } else { throw new ThrowableHolderException(ex); } } else { // A normal return value: will lead to a commit. throwableHolder.throwable = ex; return null; } } finally { cleanupTransactionInfo(txInfo); } }); // Check result state: It might indicate a Throwable to rethrow. if (throwableHolder.throwable != null) { throw throwableHolder.throwable; } return result; } catch (ThrowableHolderException ex) { throw ex.getCause(); } catch (TransactionSystemException ex2) { if (throwableHolder.throwable != null) { logger.error("Application exception overridden by commit exception", throwableHolder.throwable); ex2.initApplicationException(throwableHolder.throwable); } throw ex2; } catch (Throwable ex2) { if (throwableHolder.throwable != null) { logger.error("Application exception overridden by commit exception", throwableHolder.throwable); } throw ex2; } } }
9,jdbc的事务开启,提交和回滚,实际都是对 Connection 的操作
//开启事务 if(cnn.getAutoCommit()){ cnn.setAutoCommit(false); } //提交事务 if(!cnn.getAutoCommit()){ cnn.commit(); } //回滚事务 if(!cnn.getAutoCommit()){ cnn.rollback(); }
以上是关于Spring 事务原理的主要内容,如果未能解决你的问题,请参考以下文章