Spring注解式事务解析
来源:互联网 发布:tcp 长连接 java 框架 编辑:程序博客网 时间:2024/06/05 11:49
Spring注解式事务解析
- 首先往Spring容器新增一个Advisor,BeanFactoryTransactionAttributeSourceAdvisor,它包含了TransactionInterceptor通知和TransactionAttributeSourcePointcut切点。TransactionAttributeSourcePointcut切点实际匹配使用了AnnotationTransactionAttributeSource这个类,它的作用是方法的切点匹配,解析Transactional注解,它尝试从当前类的方法,当前类,父接口方法,父接口查找Transactional注解,有则匹配到。
- 当普通bean实例化的时候,Spring通过AbstractAdvisorAutoProxyCreator的其中一个子类进行postProcessAfterInitialization进行AOP这个bean,织入匹配的Advisor,并生成动态代理。动态代理有2种,JdkDynamicAopProxy和ObjenesisCglibAopProxy。
- 方法调用的时候,拿JdkDynamicAopProxy动态代理来讲,被动态代理的bean的公有方法调用会走invoke方法拦截,首先确定当前方法的拦截器链。
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
如果上面的chain为空,不走拦截,否则走拦截责任链
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); retVal = invocation.proceed();
- 内部拿到我们的TransactionInterceptor进行方法调用
@Override public Object invoke(final MethodInvocation invocation) throws Throwable { // Work out the target class: may be {@code null}. // The TransactionAttributeSource should be passed the target class // as well as the method, which may be from an interface. Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null); // Adapt to TransactionAspectSupport's invokeWithinTransaction... return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() { @Override public Object proceedWithInvocation() throws Throwable { return invocation.proceed(); } }); }
- 他会先获取TransactionAttribute和PlatformTransactionManager,然后调用
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
内部逻辑为拿DataSourceTransactionManager举例,
尝试从ThreadLocal获取ConnectionHolder(包含了一个Connection)
protected Object doGetTransaction() { DataSourceTransactionObject txObject = new DataSourceTransactionObject(); txObject.setSavepointAllowed(isNestedTransactionAllowed()); ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource); txObject.setConnectionHolder(conHolder, false); return txObject; }
然后判断是不是新事务
if (isExistingTransaction(transaction)) { // Existing transaction found -> check propagation behavior to find out how to behave. return handleExistingTransaction(definition, transaction, debugEnabled); }
不是新事务,走handleExistingTransaction逻辑,内部会根据我们配置的传递规则做不同的处理,默认的Propagation.REQUIRED就会返回TransactionStatus对象标志为已存在的事务。
是新事务则返回TransactionStatus对象标志为新事务,代码如下:
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER); DefaultTransactionStatus status = newTransactionStatus( definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); doBegin(transaction, definition); prepareSynchronization(status, definition); return status;
doBegin方法会从dataSource获取一个新连接,并设置到DataSourceTransactionObject的ConnectionHolder字段里,并且设置synchronizedWithTransaction和transactionActive为true代表新事务,然后设置con.setAutoCommit(false),最后设置ThreadLocal值,为当前ConnectionHolder。
if (txObject.isNewConnectionHolder()) { TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder()); }
- 获取了当前的TransactionInfo开始走下一个拦截器
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; }
- 处理完了之后如果抛异常根据匹配规则是否需要回滚,默认对RuntimeException和Error回滚。
如果正常返回则调用commitTransactionAfterReturning方法
protected void commitTransactionAfterReturning(TransactionInfo txInfo) { if (txInfo != null && txInfo.hasTransaction()) { if (logger.isTraceEnabled()) { logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]"); } txInfo.getTransactionManager().commit(txInfo.getTransactionStatus()); } }
进行commit,最后调用doCleanupAfterCompletion方法,清空ThreadLocal,设置con.setAutoCommit(true),并关闭连接。
阅读全文
0 0
- Spring注解式事务解析
- Spring注解事务诡异提交全面解析
- Spring注解式管理事务
- spring使用事务的注解解析器报错的解决方案
- Spring提取@Transactional事务注解的源码解析
- Spring注解声明式事务配置
- Spring 2.5 配置注解式事务
- spring配置声明式事务--注解方式
- Spring配置声明式事务--注解方式
- Spring声明式事务注解@Transactional
- Spring 申明式事务之注解
- Spring 基于注解方式声明式事务
- spring事务注解
- spring事务注解
- spring 事务注解
- Spring 事务注解
- Spring 注解事务说明
- Spring+Hibernate注解事务
- python模块之StringIO
- 拉格朗日对偶性
- 如何修改eclipse的默认工作空间
- python
- 【java面试系列之网络编程】TCP和UDP的区别、TCP协议的三次握手和四次挥手、TCP协议的通信状态、网络编程时的同步、异步、阻塞、非阻塞、进程间的通信方式、TCP的流量控制和拥塞控制
- Spring注解式事务解析
- Python实现归并排序
- 关于DNF的多媒体包NPK文件的那些事儿(3)
- 普通Socket的用法
- 网络工具
- R语言编程技术(1)
- spark-streaming 编程(六)mapwithState
- ActivityMQ 事务
- 小米抢购限流峰值系统「大秒」架构解密2