- 浏览: 400684 次
- 性别:
- 来自: 南京
最新评论
-
x981114171:
不知大家有没发现,国产书,国人写的书就没几本是给力的,以后国人 ...
《Spring技术内幕》的读者问题交流 -
x981114171:
买了这本书,感觉很不值。来吐槽下,也许你自己是专家,不过写的书 ...
《Spring技术内幕》的读者问题交流 -
851228082:
作者,写的书很好,我觉得幸亏有源码,所以我才能看懂。一边看,一 ...
《Spring技术内幕》的读者问题交流 -
yueshang520:
说的真不错。。学习了
Spring技术内幕——深入解析Spring架构与设计原理(一)IOC实现原理 -
faith789510:
TransactionProxyFactoryBean 什么情 ...
Spring源代码解析(六):Spring声明式事务处理
我们看看Spring中的事务处理的代码,使用Spring管理事务有声明式和编程式两种方式,声明式事务处理通过AOP的实现把事物管理代码作为方面封装来横向插入到业务代码中,使得事务管理代码和业务代码解藕。在这种方式我们结合IoC容器和Spirng已有的FactoryBean来对事务管理进行属性配置,比如传播行为,隔离级别等。其中最简单的方式就是通过配置TransactionProxyFactoryBean来实现声明式事物;
在整个源代码分析中,我们可以大致可以看到Spring实现声明式事物管理有这么几个部分:
* 对在上下文中配置的属性的处理,这里涉及的类是TransactionAttributeSourceAdvisor,这是一个通知器,用它来对属性值进行处理,属性信息放在TransactionAttribute中来使用,而这些属性的处理往往是和对切入点的处理是结合起来的。对属性的处理放在类TransactionAttributeSource中完成。
* 创建事物的过程,这个过程是委托给具体的事物管理器来创建的,但Spring通过TransactionStatus来传递相关的信息。
* 对事物的处理通过对相关信息的判断来委托给具体的事物管理器完成。
我们下面看看具体的实现,在TransactionFactoryBean中:
那什么时候Spring的TransactionInterceptor被注入到Spring AOP中成为Advisor中的一部分呢?我们看到在TransactionProxyFactoryBean中,这个方法在IOC初始化bean的时候被执行:
Spring 已经定义了一个transctionInterceptor作为拦截器或者AOP advice的实现,在IOC容器中定义的其他属性比如transactionManager和事务管理的属性都会传到已经定义好的 TransactionInterceptor那里去进行处理。以上反映了基本的Spring AOP的定义过程,其中pointcut和advice都已经定义好,同时也通过通知器配置到ProxyFactory中去了。
下面让我们回到TransactionProxyFactoryBean中看看TransactionAttributeSourceAdvisor是怎样定义的,这样我们可以理解具体的属性是怎样起作用,这里我们分析一下类TransactionAttributeSourceAdvisor:
这里我们看看属性值是怎样被读入的:AbstractFallbackTransactionAttributeSource负责具体的属性读入任务,我们可以有两种读入方式,比如annotation和直接配置.我们下面看看直接配置的读入方式,在Spring中同时对读入的属性值进行了缓存处理,这是一个decorator模式:
别急,基本的处理在computeTransactionAttribute()中:
经过一系列的尝试我们可以通过findTransactionAttribute()通过调用findAllAttribute()得到TransactionAttribute的对象,如果返回的是null,这说明该方法不是我们需要事务处理的方法。
在完成把需要的通知器加到ProxyFactory中去的基础上,我们看看具体的看事务处理代码怎样起作用,在TransactionInterceptor中:
这里面涉及到事务的创建,我们可以在TransactionAspectSupport实现的事务管理代码:
首先通过TransactionManager得到需要的事务,事务的创建根据我们定义的事务配置决定,在 AbstractTransactionManager中给出一个标准的创建过程,当然创建什么样的事务还是需要具体的 PlatformTransactionManager来决定,但这里给出了创建事务的模板:
接着通过调用prepareTransactionInfo完成事务创建的准备,创建过程中得到的信息存储在TransactionInfo对象中进行传递同时把信息和当前线程绑定;
将创建事务的信息返回,然后看到其他的事务管理代码:
通过transactionManager对事务进行处理,包括异常抛出和正常的提交事务,具体的事务管理器由用户程序设定。
Spring通过以上代码对transactionManager进行事务处理的过程进行了AOP包装,到这里我们看到为了方便客户实现声明式的事务处理,Spring还是做了许多工作的。如果说使用编程式事务处理,过程其实比较清楚,我们可以参考书中的例子:
我们看到这里选取了默认的事务配置DefaultTransactionDefinition,同时在创建事物的过程中得到TransactionStatus,然后通过直接调用事务管理器的相关方法就能完成事务处理。
声明式事务处理也同样实现了类似的过程,只是因为采用了声明的方法,需要增加对属性的读取处理,并且需要把整个过程整合到Spring AOP框架中和IoC容器中去的过程。
下面我们选取一个具体的transactionManager - DataSourceTransactionManager来看看其中事务处理的实现:
同样的通过使用AbstractPlatformTransactionManager使用模板方法,这些都体现了对具体平台相关的事务管理器操作的封装,比如commit:
通过对TransactionStatus的具体状态的判断,来决定具体的事务处理:
这些模板方法的实现由具体的transactionManager来实现,比如在DataSourceTransactionManager:
我们看到在DataSourceTransactionManager中最后还是交给connection来实现事务的提交和rollback。整个声明式事务处理是事务处理在Spring AOP中的应用,我们看到了一个很好的使用Spring AOP的例子,在Spring声明式事务处理的源代码中我们可以看到:
1.怎样封装各种不同平台下的事务处理代码
2.怎样读取属性值和结合事务处理代码来完成既定的事务处理策略
3.怎样灵活的使用SpringAOP框架。
如果能够结合前面的Spring AOP的源代码来学习,理解可能会更深刻些。
大概总结一下,可以关注这几个类的实现:
TransactionInterceptor - 是使用AOP实现声明式事务处理的拦截器,封装了Spring对声明式事务处理的实现。
TransactionAttributeSource和TransactionAttribute - 这里封装对声明式事务处理属性的识别,信息的读入和配置
TransactionInfo ,TransactionStatus - 这是事务处理信息存放的主要地方,而且是和线程绑定的。
然后就是TransactionManager, 通过使用TransactionInfo和TransactionStatus来控制事务处理 - 中间的一些和具体事务处理器无关的操作封装到AbstractPlatformTransactionManager里面实现了。
对编程式的事务处理TransactionDefinition是定义事务属性的类,Spring提供了DefaultTransactionDefinition供用户使用。
在整个源代码分析中,我们可以大致可以看到Spring实现声明式事物管理有这么几个部分:
* 对在上下文中配置的属性的处理,这里涉及的类是TransactionAttributeSourceAdvisor,这是一个通知器,用它来对属性值进行处理,属性信息放在TransactionAttribute中来使用,而这些属性的处理往往是和对切入点的处理是结合起来的。对属性的处理放在类TransactionAttributeSource中完成。
* 创建事物的过程,这个过程是委托给具体的事物管理器来创建的,但Spring通过TransactionStatus来传递相关的信息。
* 对事物的处理通过对相关信息的判断来委托给具体的事物管理器完成。
我们下面看看具体的实现,在TransactionFactoryBean中:
public class TransactionProxyFactoryBean extends AbstractSingletonProxyFactoryBean implements FactoryBean, BeanFactoryAware { //这里是Spring事务处理而使用的AOP拦截器,中间封装了Spring对事务处理的代码来支持声明式事务处理的实现 private final TransactionInterceptor transactionInterceptor = new TransactionInterceptor(); private Pointcut pointcut; //这里Spring把TransactionManager注入到TransactionInterceptor中去 public void setTransactionManager(PlatformTransactionManager transactionManager) { this.transactionInterceptor.setTransactionManager(transactionManager); } //这里把在bean配置文件中读到的事务管理的属性信息注入到TransactionInterceptor中去 public void setTransactionAttributes(Properties transactionAttributes) { this.transactionInterceptor.setTransactionAttributes(transactionAttributes); } .........中间省略了其他一些方法....... //这里创建Spring AOP对事务处理的Advisor protected Object createMainInterceptor() { this.transactionInterceptor.afterPropertiesSet(); if (this.pointcut != null) { //这里使用默认的通知器 return new DefaultPointcutAdvisor(this.pointcut, this.transactionInterceptor); } else { // 使用上面定义好的TransactionInterceptor作为拦截器,同时使用TransactionAttributeSourceAdvisor return new TransactionAttributeSourceAdvisor(this.transactionInterceptor); } } }
那什么时候Spring的TransactionInterceptor被注入到Spring AOP中成为Advisor中的一部分呢?我们看到在TransactionProxyFactoryBean中,这个方法在IOC初始化bean的时候被执行:
public void afterPropertiesSet() { ....... //TransactionProxyFactoryBean实际上使用ProxyFactory完成AOP的基本功能。 ProxyFactory proxyFactory = new ProxyFactory(); if (this.preInterceptors != null) { for (int i = 0; i < this.preInterceptors.length; i++) { proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(this.preInterceptors[i])); } } //这里是Spring加入通知器的地方 //有两种通知器可以被加入DefaultPointcutAdvisor或者TransactionAttributeSourceAdvisor //这里把Spring处理声明式事务处理的AOP代码都放到ProxyFactory中去,怎样加入advisor我们可以参考ProxyFactory的父类AdvisedSupport() //由它来维护一个advice的链表,通过这个链表的增删改来抽象我们对整个通知器配置的增删改操作。 proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(createMainInterceptor())); if (this.postInterceptors != null) { for (int i = 0; i < this.postInterceptors.length; i++) { proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(this.postInterceptors[i])); } } proxyFactory.copyFrom(this); //这里创建AOP的目标源 TargetSource targetSource = createTargetSource(this.target); proxyFactory.setTargetSource(targetSource); if (this.proxyInterfaces != null) { proxyFactory.setInterfaces(this.proxyInterfaces); } else if (!isProxyTargetClass()) { proxyFactory.setInterfaces(ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass())); } this.proxy = getProxy(proxyFactory); }
Spring 已经定义了一个transctionInterceptor作为拦截器或者AOP advice的实现,在IOC容器中定义的其他属性比如transactionManager和事务管理的属性都会传到已经定义好的 TransactionInterceptor那里去进行处理。以上反映了基本的Spring AOP的定义过程,其中pointcut和advice都已经定义好,同时也通过通知器配置到ProxyFactory中去了。
下面让我们回到TransactionProxyFactoryBean中看看TransactionAttributeSourceAdvisor是怎样定义的,这样我们可以理解具体的属性是怎样起作用,这里我们分析一下类TransactionAttributeSourceAdvisor:
public class TransactionAttributeSourceAdvisor extends AbstractPointcutAdvisor { //和其他Advisor一样,同样需要定义AOP中的用到的Interceptor和Pointcut //Interceptor使用传进来的TransactionInterceptor //而对于pointcut,这里定义了一个内部类,参见下面的代码 private TransactionInterceptor transactionInterceptor; private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut(); ......... //定义的PointCut内部类 private class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable { ....... //方法匹配的实现,使用了TransactionAttributeSource类 public boolean matches(Method method, Class targetClass) { TransactionAttributeSource tas = getTransactionAttributeSource(); //这里使用TransactionAttributeSource来对配置属性进行处理 return (tas != null && tas.getTransactionAttribute(method, targetClass) != null); } ........省略了equal,hashcode,tostring的代码 }
这里我们看看属性值是怎样被读入的:AbstractFallbackTransactionAttributeSource负责具体的属性读入任务,我们可以有两种读入方式,比如annotation和直接配置.我们下面看看直接配置的读入方式,在Spring中同时对读入的属性值进行了缓存处理,这是一个decorator模式:
public final TransactionAttribute getTransactionAttribute(Method method, Class targetClass) { //这里先查一下缓存里有没有事务管理的属性配置,如果有从缓存中取得TransactionAttribute Object cacheKey = getCacheKey(method, targetClass); Object cached = this.cache.get(cacheKey); if (cached != null) { if (cached == NULL_TRANSACTION_ATTRIBUTE) { return null; } else { return (TransactionAttribute) cached; } } else { // 这里通过对方法和目标对象的信息来计算事务缓存属性 TransactionAttribute txAtt = computeTransactionAttribute(method, targetClass); //把得到的事务缓存属性存到缓存中,下次可以直接从缓存中取得。 if (txAtt == null) { this.cache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE); } else { ........... this.cache.put(cacheKey, txAtt); } return txAtt; } }
别急,基本的处理在computeTransactionAttribute()中:
private TransactionAttribute computeTransactionAttribute(Method method, Class targetClass) { //这里检测是不是public方法 if(allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) { return null; } Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass); // First try is the method in the target class. TransactionAttribute txAtt = findTransactionAttribute(findAllAttributes(specificMethod)); if (txAtt != null) { return txAtt; } // Second try is the transaction attribute on the target class. txAtt = findTransactionAttribute(findAllAttributes(specificMethod.getDeclaringClass())); if (txAtt != null) { return txAtt; } if (specificMethod != method) { // Fallback is to look at the original method. txAtt = findTransactionAttribute(findAllAttributes(method)); if (txAtt != null) { return txAtt; } // Last fallback is the class of the original method. return findTransactionAttribute(findAllAttributes(method.getDeclaringClass())); } return null; }
经过一系列的尝试我们可以通过findTransactionAttribute()通过调用findAllAttribute()得到TransactionAttribute的对象,如果返回的是null,这说明该方法不是我们需要事务处理的方法。
在完成把需要的通知器加到ProxyFactory中去的基础上,我们看看具体的看事务处理代码怎样起作用,在TransactionInterceptor中:
public Object invoke(final MethodInvocation invocation) throws Throwable { //这里得到目标对象 Class targetClass = (invocation.getThis() != null ? invocation.getThis().getClass() : null); //这里同样的通过判断是否能够得到TransactionAttribute来决定是否对当前方法进行事务处理,有可能该属性已经被缓存, //具体可以参考上面对getTransactionAttribute的分析,同样是通过TransactionAttributeSource final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(invocation.getMethod(), targetClass); final String joinpointIdentification = methodIdentification(invocation.getMethod()); //这里判断我们使用了什么TransactionManager if (txAttr == null || !(getTransactionManager() instanceof CallbackPreferringPlatformTransactionManager)) { // 这里创建事务,同时把创建事务过程中得到的信息放到TransactionInfo中去 TransactionInfo txInfo = createTransactionIfNecessary(txAttr, joinpointIdentification); Object retVal = null; try { retVal = invocation.proceed(); } catch (Throwable ex) { // target invocation exception completeTransactionAfterThrowing(txInfo, ex); throw ex; } finally { cleanupTransactionInfo(txInfo); } commitTransactionAfterReturning(txInfo); return retVal; } else { // 使用的是Spring定义的PlatformTransactionManager同时实现了回调接口,我们通过其回调函数完成事务处理,就像我们使用编程式事务处理一样。 try { Object result = ((CallbackPreferringPlatformTransactionManager) getTransactionManager()).execute(txAttr, new TransactionCallback() { public Object doInTransaction(TransactionStatus status) { //同样的需要一个TransactonInfo TransactionInfo txInfo = prepareTransactionInfo(txAttr, joinpointIdentification, status); try { return invocation.proceed(); } .....这里省去了异常处理和事务信息的清理代码 }); ........... } }
这里面涉及到事务的创建,我们可以在TransactionAspectSupport实现的事务管理代码:
protected TransactionInfo createTransactionIfNecessary( TransactionAttribute txAttr, final String joinpointIdentification) { // If no name specified, apply method identification as transaction name. if (txAttr != null && txAttr.getName() == null) { txAttr = new DelegatingTransactionAttribute(txAttr) { public String getName() { return joinpointIdentification; } }; } TransactionStatus status = null; if (txAttr != null) { //这里使用了我们定义好的事务配置信息,有事务管理器来创建事务,同时返回TransactionInfo status = getTransactionManager().getTransaction(txAttr); } return prepareTransactionInfo(txAttr, joinpointIdentification, status); }
首先通过TransactionManager得到需要的事务,事务的创建根据我们定义的事务配置决定,在 AbstractTransactionManager中给出一个标准的创建过程,当然创建什么样的事务还是需要具体的 PlatformTransactionManager来决定,但这里给出了创建事务的模板:
public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException { Object transaction = doGetTransaction(); ...... if (definition == null) { //如果事务信息没有被配置,我们使用Spring默认的配置方式 definition = new DefaultTransactionDefinition(); } if (isExistingTransaction(transaction)) { // Existing transaction found -> check propagation behavior to find out how to behave. return handleExistingTransaction(definition, transaction, debugEnabled); } // Check definition settings for new transaction. //下面就是使用配置信息来创建我们需要的事务;比如传播属性和同步属性等 //最后把创建过程中的信息收集起来放到TransactionStatus中返回; if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) { throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout()); } // No existing transaction found -> check propagation behavior to find out how to behave. if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) { throw new IllegalTransactionStateException( "Transaction propagation 'mandatory' but no existing transaction found"); } else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED || definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW || definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) { //这里是事务管理器创建事务的地方,并将创建过程中得到的信息放到TransactionStatus中去,包括创建出来的事务 doBegin(transaction, definition); boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER); return newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, null); } else { boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS); return newTransactionStatus(definition, null, false, newSynchronization, debugEnabled, null); } }
接着通过调用prepareTransactionInfo完成事务创建的准备,创建过程中得到的信息存储在TransactionInfo对象中进行传递同时把信息和当前线程绑定;
protected TransactionInfo prepareTransactionInfo( TransactionAttribute txAttr, String joinpointIdentification, TransactionStatus status) { TransactionInfo txInfo = new TransactionInfo(txAttr, joinpointIdentification); if (txAttr != null) { ..... // 同样的需要把在getTransaction中得到的TransactionStatus放到TransactionInfo中来。 txInfo.newTransactionStatus(status); } else { ....... } // 绑定事务创建信息到当前线程 txInfo.bindToThread(); return txInfo; }
将创建事务的信息返回,然后看到其他的事务管理代码:
protected void commitTransactionAfterReturning(TransactionInfo txInfo) { if (txInfo != null && txInfo.hasTransaction()) { if (logger.isDebugEnabled()) { logger.debug("Invoking commit for transaction on " + txInfo.getJoinpointIdentification()); } this.transactionManager.commit(txInfo.getTransactionStatus()); } }
通过transactionManager对事务进行处理,包括异常抛出和正常的提交事务,具体的事务管理器由用户程序设定。
protected void completeTransactionAfterThrowing(TransactionInfo txInfo, Throwable ex) { if (txInfo != null && txInfo.hasTransaction()) { if (txInfo.transactionAttribute.rollbackOn(ex)) { ...... try { this.transactionManager.rollback(txInfo.getTransactionStatus()); } .......... } else { ......... try { this.transactionManager.commit(txInfo.getTransactionStatus()); } ........... } protected void commitTransactionAfterReturning(TransactionInfo txInfo) { if (txInfo != null && txInfo.hasTransaction()) { ...... this.transactionManager.commit(txInfo.getTransactionStatus()); } }
Spring通过以上代码对transactionManager进行事务处理的过程进行了AOP包装,到这里我们看到为了方便客户实现声明式的事务处理,Spring还是做了许多工作的。如果说使用编程式事务处理,过程其实比较清楚,我们可以参考书中的例子:
TransactionDefinition td = new DefaultTransactionDefinition(); TransactionStatus status = transactionManager.getTransaction(td); try{ ......//这里是我们的业务方法 }catch (ApplicationException e) { transactionManager.rollback(status); throw e } transactionManager.commit(status); ........
我们看到这里选取了默认的事务配置DefaultTransactionDefinition,同时在创建事物的过程中得到TransactionStatus,然后通过直接调用事务管理器的相关方法就能完成事务处理。
声明式事务处理也同样实现了类似的过程,只是因为采用了声明的方法,需要增加对属性的读取处理,并且需要把整个过程整合到Spring AOP框架中和IoC容器中去的过程。
下面我们选取一个具体的transactionManager - DataSourceTransactionManager来看看其中事务处理的实现:
同样的通过使用AbstractPlatformTransactionManager使用模板方法,这些都体现了对具体平台相关的事务管理器操作的封装,比如commit:
public final void commit(TransactionStatus status) throws TransactionException { ...... DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status; if (defStatus.isLocalRollbackOnly()) { ...... processRollback(defStatus); return; } ....... processRollback(defStatus); ...... } processCommit(defStatus); }
通过对TransactionStatus的具体状态的判断,来决定具体的事务处理:
private void processCommit(DefaultTransactionStatus status) throws TransactionException { try { boolean beforeCompletionInvoked = false; try { triggerBeforeCommit(status); triggerBeforeCompletion(status); beforeCompletionInvoked = true; boolean globalRollbackOnly = false; if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) { globalRollbackOnly = status.isGlobalRollbackOnly(); } if (status.hasSavepoint()) { ........ status.releaseHeldSavepoint(); } else if (status.isNewTransaction()) { ...... doCommit(status); } ......... }
这些模板方法的实现由具体的transactionManager来实现,比如在DataSourceTransactionManager:
protected void doCommit(DefaultTransactionStatus status) { //这里得到存在TransactionInfo中已经创建好的事务 DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction(); //这里得到和事务绑定的数据库连接 Connection con = txObject.getConnectionHolder().getConnection(); ........ try { //这里通过数据库连接来提交事务 con.commit(); } ....... } protected void doRollback(DefaultTransactionStatus status) { DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction(); Connection con = txObject.getConnectionHolder().getConnection(); if (status.isDebug()) { logger.debug("Rolling back JDBC transaction on Connection [" + con + "]"); } try { //这里通过数据库连接来回滚事务 con.rollback(); } catch (SQLException ex) { throw new TransactionSystemException("Could not roll back JDBC transaction", ex); } }
我们看到在DataSourceTransactionManager中最后还是交给connection来实现事务的提交和rollback。整个声明式事务处理是事务处理在Spring AOP中的应用,我们看到了一个很好的使用Spring AOP的例子,在Spring声明式事务处理的源代码中我们可以看到:
1.怎样封装各种不同平台下的事务处理代码
2.怎样读取属性值和结合事务处理代码来完成既定的事务处理策略
3.怎样灵活的使用SpringAOP框架。
如果能够结合前面的Spring AOP的源代码来学习,理解可能会更深刻些。
评论
5 楼
faith789510
2016-01-13
TransactionProxyFactoryBean 什么情况下,什么时候起作用,在xml里面没有配置
4 楼
bennyparlo
2007-09-28
好久没来回帖了,由于最近正好在工作作用使用到了spring的事务管理,所以我也来总结下
spring已经提供了声明式的事务管理模型,这主要借用了基于ioc容器实现的aop编程框架,利用类似拦截器的方式将定义需要进行事务处理的bean方法进行代理封装.
当然其核心部分还在于其自身实现的事务管理,因此这里就从编程式的事务管理开始讲起.
首先,对于事务的定义可以通过TransactionDefinition接口的实现来进行描述,当然spring已经提供了最常用的DefaultTransactionDefinition实现.这个设计的思想又不禁让人想起了ioc容器中用到的BeanDefinition以及其默认实现DefaultBeanDefinition.这样设计的主要目的在于将定义的描述对象与其每个实例进行隔离.
而对于被创建的事务对象将通过TransactionStatus来进行封装,当然该接口也有继承于AbstractTransactionStatus的默认实现DefaultTransactionStatus.因此在1个事务方法中,事务管理器将根据TransactionStatus的实例对象进行commit,rollback等操作.但这里值得1提的是,如果以
DefaultTransactionStatus为例,该类中封装了private final Object transaction对象.这里的transaction在运行期将是个SmartTransactionObject的实现对象,如JdbcTransactionObjectSupport或者DataSourceTransactionObject或者JtaTransactionObject,当然这里的DataSourceTransactionObject是个内部类,它继承了DataSourceTransactionObjectSupport.
再以DataSourceTransactionObject为例,在该类的父类DataSourceTransactionObjectSupport中,封装了private ConnectionHolder connectionHolder,而该connectionHolder对象又绑定了private Connection currentConnection.这里其实是事务实现的核心所在了,在接下来的讲述中会发现,jdbc事务的最终操作其实就委托给currentConnection来做进行相应的处理.
spring已经提供了声明式的事务管理模型,这主要借用了基于ioc容器实现的aop编程框架,利用类似拦截器的方式将定义需要进行事务处理的bean方法进行代理封装.
当然其核心部分还在于其自身实现的事务管理,因此这里就从编程式的事务管理开始讲起.
首先,对于事务的定义可以通过TransactionDefinition接口的实现来进行描述,当然spring已经提供了最常用的DefaultTransactionDefinition实现.这个设计的思想又不禁让人想起了ioc容器中用到的BeanDefinition以及其默认实现DefaultBeanDefinition.这样设计的主要目的在于将定义的描述对象与其每个实例进行隔离.
而对于被创建的事务对象将通过TransactionStatus来进行封装,当然该接口也有继承于AbstractTransactionStatus的默认实现DefaultTransactionStatus.因此在1个事务方法中,事务管理器将根据TransactionStatus的实例对象进行commit,rollback等操作.但这里值得1提的是,如果以
DefaultTransactionStatus为例,该类中封装了private final Object transaction对象.这里的transaction在运行期将是个SmartTransactionObject的实现对象,如JdbcTransactionObjectSupport或者DataSourceTransactionObject或者JtaTransactionObject,当然这里的DataSourceTransactionObject是个内部类,它继承了DataSourceTransactionObjectSupport.
再以DataSourceTransactionObject为例,在该类的父类DataSourceTransactionObjectSupport中,封装了private ConnectionHolder connectionHolder,而该connectionHolder对象又绑定了private Connection currentConnection.这里其实是事务实现的核心所在了,在接下来的讲述中会发现,jdbc事务的最终操作其实就委托给currentConnection来做进行相应的处理.
3 楼
jiwenke
2007-06-23
autumnxian 写道
文章太长了,能不能概括一下有哪几个类的代码是重点?
大概总结一下,可以关注这几个类的实现:
TransactionInterceptor - 是使用AOP实现声明式事务处理的拦截器,封装了Spring对声明式事务处理的实现。
TransactionAttributeSource和TransactionAttribute - 这里封装对声明式事务处理属性的识别,信息的读入和配置
TransactionInfo ,TransactionStatus - 这是事务处理信息存放的主要地方,而且是和线程绑定的。
然后就是TransactionManager, 通过使用TransactionInfo和TransactionStatus来控制事务处理 - 中间的一些和具体事务处理器无关的操作封装到AbstractPlatformTransactionManager里面实现了。
对编程式的事务处理TransactionDefinition是定义事务属性的类,Spring提供了DefaultTransactionDefinition供用户使用。
2 楼
autumnxian
2007-06-21
文章太长了,能不能概括一下有哪几个类的代码是重点?
1 楼
jiwenke
2007-06-10
这几天把贴子重新更新了一遍,发现很多错误和思路上不清楚的地方,欢迎拍砖,我会继续更新贴子的。
发表评论
-
开放注册了!我们的任务推客 - 群组任务和流程协同SaaS工具
2010-06-30 20:31 621经过这几天团队的努力,为软件增加了开放注册功能,大家可以自己动 ... -
我们团队研发的SaaS软件产品:应用于群组任务协同和流程管理
2010-06-21 15:39 846任务协同及流程管理SaaS软件:任务推客上线,欢迎大家免费体验 ... -
随笔:Spring与云计算(六)
2009-12-17 18:49 3771这样,就说到国内了, ... -
随笔:Spring与云计算(五)
2009-12-16 19:58 3383那其他呢,我们看看还 ... -
随笔:Spring与云计算(四)
2009-12-15 16:26 4151前面我们提到,Spring被VMWare收购而进入云计算领域, ... -
随笔:Spring与云计算(三)
2009-12-14 14:05 3725在前面的那张图中,可以看到SpringSource产品和云计算 ... -
随笔:Spring与云计算(二)
2009-12-11 14:57 4305这么大的范围的模式转 ... -
随笔:Spring与云计算(一)
2009-12-10 15:19 6965对Spring和云计算的关注 ... -
《Spring技术内幕 - 深入解析Spring架构与设计原理》上市了!
2009-12-09 15:17 9107详细的书本目录和章节节选请见附件!欢迎下载指正。 可以购买到 ... -
Spring技术内幕——深入解析Spring架构与设计原理(六)Spring ACEGI
2009-11-20 12:27 14533Spring ACEGI 作为Spring丰富生态系统中的一个 ... -
Spring技术内幕——深入解析Spring架构与设计原理(五)Spring与远端调用
2009-11-16 20:23 11168在应用开发中,常常涉及服务器系统中各种不同进程之间的通信与计算 ... -
Spring技术内幕——深入解析Spring架构与设计原理(四)Web MVC的实现
2009-11-08 08:55 21226以前的欠账,现在补上,欢迎指正和讨论。 Spring Web ... -
Spring技术内幕——深入解析Spring架构与设计原理(三)数据库的操作实现
2009-11-02 17:34 13785最近事情实在是比较多,没有及时更新帖子,还望大家见谅啊。今天, ... -
Spring技术内幕——深入解析Spring架构与设计原理(二)AOP
2009-10-20 08:30 23077关于AOP的个人理解 AOP联盟定义的AOP体系结构把与AO ... -
Spring技术内幕——深入解析Spring架构与设计原理(一)IOC实现原理
2009-10-19 10:47 98949内容较多,新开一贴, ... -
Spring技术内幕——深入解析Spring架构与设计原理(一)引子
2009-10-17 20:31 11247缘起 已经很久没有写 ... -
Hadoop的mapred JobTracker端源码概览
2009-02-18 19:40 5205上一节看到TaskTracker启动新任务的过程,这里接着看看 ... -
Hadoop的mapred TaskTracker端源码概览
2009-02-17 14:39 4113花了许多功夫把Hadoop的mapreduce实现过了一遍,基 ... -
Hadoop的mapred TaskTracker端源码概览
2009-02-17 14:37 1651这篇文章和博客的另一篇重复,删掉了。对不起,请参阅博客的另一篇 ... -
发布用javaeye生成的博客版本 - Spring源代码解析
2008-11-20 08:49 3633呵呵,试试javaeye的新功能。帮助大家阅读,文中的很多错误 ...
相关推荐
Spring源代码解析6:Spring声明式事务处理 .doc Spring源代码解析7:Spring AOP中对拦截器调用的实现 .doc Spring源代码解析8:Spring驱动Hibernate的实现.doc Spring源代码解析9:Spring Acegi框架鉴权的实现.doc ...
Spring源代码解析6:Spring声明式事务处理 ; Spring源代码解析7:Spring AOP中对拦截器调用的实现 Spring源代码解析8:Spring驱动Hibernate的实现;Spring源代码解析9:Spring Acegi框架鉴权的实现 Spring源...
Spring源代码解析(六):Spring声明式事务处理 Spring源代码解析(七):Spring AOP中对拦截器调用的实现 Spring源代码解析(八):Spring驱动Hibernate的实现 Spring源代码解析(九):Spring Acegi框架鉴权的实现 ...
在整个源代码分析中,我们可以看到 Spring 实现声明式事务管理有三个部分: 1. 对在上下文中配置的属性的处理,这里涉及的类是 TransactionAttributeSourceAdvisor,这是一个通知器,用它来对属性值进行处理,属性...
pring源代码解析1:IOC容器;Spring源代码解析2:IoC...Spring源代码解析6:Spring声明式事务处理 ; Spring源代码解析7:Spring AOP中对拦截器调用的实现 Spring源代码解析8:Spring驱动Hibernate的实现;Spring源代
5. **事务管理**:"spring源代码解析(六):spring声明式事物处理.doc"分析了Spring如何提供声明式事务管理,包括@Transactional注解的工作原理和事务传播行为。 6. **Spring与Hibernate集成**:"spring源代码解析...
Spring源代码解析(六):Spring声明式事务处理.doc Spring源代码解析(七):Spring AOP中对拦截器调用的实现.doc Spring源代码解析(八):Spring驱动Hibernate的实现.doc Spring源代码解析(九):Spring Acegi...
《Spring源代码解析》 Spring框架作为Java领域最流行的开源框架之一,它的设计思想和实现方式一直是广大开发者关注的焦点。深入理解Spring的源代码,能够帮助我们更好地掌握其工作原理,提高我们的开发效率和代码...
在这个"spring声明式事务处理demo"中,我们将探讨如何在MyEclipse环境下实现这一功能。 首先,我们要理解Spring事务管理的两种主要方式:编程式事务管理和声明式事务管理。编程式事务管理通常通过AOP(面向切面编程...
Spring框架是Java开发中最常用的轻量级框架之一,它的核心特性包括依赖注入(Dependency Injection,DI)、面向切面编程(Aspect-Oriented Programming,AOP)以及声明式事务管理等。这个“Spring源代码解析”压缩包...
本资源包含两个文件:“Spring声明式事务处理.wrf”和“testtrans”,很可能是示例代码或者测试用例,用于演示如何在Java应用中使用Spring进行声明式事务处理。 首先,让我们深入理解声明式事务处理的概念。声明式...
它提供了声明式事务管理,使得事务处理更加简单。例如,`@Transactional`注解可以方便地进行事务控制。 6. **Spring Boot**: Spring Boot简化了Spring应用程序的启动和配置,通过自动配置和起步依赖,让开发者...
总的来说,Spring 3和Hibernate 4结合使用声明式事务管理,使得我们无需在代码中显式调用事务开始、提交和回滚,而是通过注解和配置文件来声明事务的边界和行为。这种方式降低了代码的复杂度,提高了可维护性和可...
在Spring框架中,声明式事务管理是实现事务处理...在博文"Spring使用XML配置声明式事务"中,作者详细讲解了每个步骤,并可能通过示例代码展示了如何实际应用这些配置,帮助读者更好地理解和掌握Spring声明式事务管理。
Spring提供了声明式事务管理,允许我们在不直接编写事务控制代码的情况下,通过配置实现事务的回滚和提交。`PlatformTransactionManager`接口和相关的事务策略类是事务管理的核心。通过源码分析,我们可以理解Spring...