- 浏览: 756930 次
- 性别:
- 来自: 郑州
文章分类
- 全部博客 (396)
- JAVA (50)
- ORACLE (22)
- HIBERNATE (1)
- SPRING (26)
- STRUTS (4)
- OTHERS (0)
- MYSQL (11)
- Struts2 (16)
- JS (33)
- Tomcat (6)
- DWR (1)
- JQuery (26)
- JBoss (0)
- SQL SERVER (0)
- XML (10)
- 生活 (3)
- JSP (11)
- CSS (5)
- word (1)
- MyEclipse (7)
- JSTL (1)
- JEECMS (2)
- Freemarker (8)
- 页面特效 (1)
- EXT (2)
- Web前端 js库 (2)
- JSON http://www.json.org (3)
- 代码收集 (1)
- 电脑常识 (6)
- MD5加密 (0)
- Axis (0)
- Grails (1)
- 浏览器 (1)
- js调试工具 (1)
- WEB前端 (5)
- JDBC (2)
- PowerDesigner (1)
- OperaMasks (1)
- CMS (1)
- Java开源大全 (2)
- 分页 (28)
- Eclipse插件 (1)
- Proxool (1)
- Jad (1)
- Java反编译 (2)
- 报表 (6)
- JSON (14)
- FCKeditor (9)
- SVN (1)
- ACCESS (1)
- 正则表达式 (3)
- 数据库 (1)
- Flex (3)
- pinyin4j (2)
- IBATIS (3)
- probe (1)
- JSP & Servlet (1)
- 飞信 (0)
- AjaxSwing (0)
- AjaxSwing (0)
- Grid相关 (1)
- HTML (5)
- Guice (4)
- Warp framework (1)
- warp-persist (1)
- 服务器推送 (3)
- eclipse (1)
- JForum (5)
- 工具 (1)
- Python (1)
- Ruby (1)
- SVG (3)
- Joda-Time日期时间工具 (1)
- JDK (3)
- Pushlet (2)
- JSP & Servlet & FTP (1)
- FTP (6)
- 时间与效率 (4)
- 二维码 (1)
- 条码/二维码 (1)
最新评论
-
ctrlc:
你这是从web服务器上传到FTP服务器上的吧,能从用户电脑上上 ...
jsp 往 FTP 上传文件问题 -
annybz:
说的好抽象 为什么代码都有两遍。这个感觉没有第一篇 和第二篇 ...
Spring源代码解析(三):Spring JDBC -
annybz:
...
Spring源代码解析(一):IOC容器 -
jie_20:
你确定你有这样配置做过测试? 请不要转载一些自己没有测试的文档 ...
Spring2.0集成iReport报表技术概述 -
asd51731:
大哥,limit传-1时出错啊,怎么修改啊?
mysql limit 使用方法
我们看看Spring中的事务处理的代码,使用Spring管理事务有声明式和编程式两种方式,声明式事务处理通过AOP的实现把事物管理代码作为
方面封装来横向插入到业务代码中,使得事务管理代码和业务代码解藕。在这种方式我们结合IoC容器和Spirng已有的FactoryBean来对事务管
理进行属性配置,比如传播行为,隔离级别等。其中最简单的方式就是通过配置TransactionProxyFactoryBean来实现声明式事物;
在
整个源代码分析中,我们可以大致可以看到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);
- }
- }
- }
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);
- }
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的代码
- }
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;
- }
- }
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 ;
- }
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();
- }
- .....这里省去了异常处理和事务信息的清理代码
- });
- ...........
- }
- }
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);
- }
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 );
- }
- }
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 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());
- }
- }
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());
- }
- }
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);
- ........
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);
- }
public final void commit(TransactionStatus status) throws TransactionException { ...... DefaultTransactionStatus defStatus = (DefaultT发表评论
-
Spring--quartz中cronExpression配置说明
2011-12-02 18:28 0quartz中cronExpression配置说明 字段 ... -
使用Spring的jdbcTemplate进一步简化JDBC操作
2011-12-02 09:20 1270先看applicationContext.xml配置文件: ... -
Spring MVC:使用SimpleUrlHandlerMapping的一个简单例子
2011-12-01 11:26 971实现一个控制器ShirdrnCon ... -
最简单的Spring MVC入门示例
2010-05-19 14:29 1534应一位朋友的要求,写一个最简单的spring示例,使用s ... -
Spring源代码解析(十):Spring Acegi框架授权的实现
2010-03-18 12:48 1530我们从FilterSecurityIntercep ... -
Spring源代码解析(九):Spring Acegi框架鉴权的实现
2010-03-18 12:47 1513简单分析一下Spring Acegi的源代码实现: Ser ... -
Spring源代码解析(八):Spring驱动Hibernate的实现
2010-03-18 12:41 1455O/R工具出现之后,简化了许多复杂的信息持久化的开发。Spri ... -
Spring源代码解析(七):Spring AOP中对拦截器调用的实现
2010-03-18 12:40 1426前面我们分析了Spring AOP实现中得到Proxy对象的过 ... -
Spring源代码解析(五):Spring AOP获取Proxy
2010-03-18 12:36 1329下面我们来看看Spring的AOP的一些相关代码是怎么得到Pr ... -
Spring源代码解析(四):Spring MVC
2010-03-18 12:35 7752下面我们对Spring MVC框架代码进行分析,对于web ... -
Spring源代码解析(三):Spring JDBC
2010-03-18 12:33 1704下面我们看看Spring JDBC相关的实现, 在Spri ... -
Spring源代码解析(二):IoC容器在Web容器中的启动
2010-03-18 12:32 1453上面我们分析了IOC容器本身的实现,下面我们看看在典型的web ... -
Spring源代码解析(一):IOC容器
2010-03-18 12:30 2679在Spring中,IOC容器的重要地位我们就不多说了,对于Sp ... -
使用Spring的JdbcTemplate和BeanPropertyRowMapper完成的JDBC
2010-03-18 12:08 2251先道要加上两个包:Spring2.5下面的: spring. ... -
使用Spring的SimpleJdbcTemplate完成DAO操作
2010-03-18 12:06 1515l SimpleJdbcTemplate内部包含了 ... -
使用Spring的NamedParameterJdbcTemplate完成DAO操作
2010-03-18 12:05 1437NamedParameterJdbcTemplate内部包含了 ... -
Spring in Action 学习笔记—第四章 征服数据库(转)
2010-03-18 12:03 1259Spring2.0正式版(http://www.springf ... -
Spring管理JDBC连接
2010-03-18 11:59 1697在Spring中,JdbcTemplate是经常被使用的类来帮 ... -
Spring JDBC数据库操作类
2010-03-18 09:26 16501.JdbcTemplate 在Spring中, ... -
Spring JdbcTemplate 批量插入或更新操作
2010-03-18 09:19 5289用 JdbcTemplate 进行批量插入或更新操作 ...
相关推荐
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...