`
Feiing
  • 浏览: 240080 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Spring 事务简化配置

阅读更多
在 spring 中,  事务管理一般是通过声明一个 txProxyTemplate,  然后业务 bean 中 parent = "txProxyTemplate",  这样做未免显得有些繁琐,  并且如果业务 bean 还需要其他拦截器,  配置也不太方便,  下面贴出我的配置, 用 DefaultAdvisorAutoProxyCreator 实现自动代理

<beans>
	<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
    <bean id="transactionManager"
          class="org.springframework.orm.hibernate3.HibernateTransactionManager">
          <property name="sessionFactory">
              <ref bean="sessionFactory"/>
          </property>
    </bean>	
	
	<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
    	<property name="transactionManager" ref="transactionManager"/>
		<property name="transactionAttributeSource">
		  <value>
			com.skyon.user.manager.UserManager.*=PROPAGATION_REQUIRED
			#Add new defines here ->
		  </value>
		</property>
	</bean>
	
	<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
		<property name="interceptorNames">
			<list>
				<value>transactionInterceptor</value>
				<!--
				增加新的 Interceptor
				-->
			</list>
		</property>
	</bean>

	<bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
	  <property name="transactionInterceptor" ref="transactionInterceptor"/>
	</bean>
		
</beans>



这里利用 DefaultAdvisorAutoProxyCreator 实现了对容器中所有 bean 的自动代理,  增加一个需要事务的业务 bean 时只要在 transactionInterceptor 增加一行即可,  增加别的 interceptor 也非常方便,
极大减少了配置量
分享到:
评论
24 楼 hongliang 2006-03-24  
我觉得当然是用BeanNameAutoProxyCreator方便,不然每次加service都还要跑去改transactionAttributeSource太麻烦叻
23 楼 kevinming 2006-03-23  
nihongye 写道
引用
transactionAttributeSource好像是必须要指明方法名才行,而transactionAttributes则不需要。。。
transactionAttributeSource
使用&lt;value&gt;xx.xx*=PRO...&lt;/value&gt;这种写法,spring使用TransactionAttributeSourceEdtior对value进行处理,创建出一个MethodName..AttributeSource实例来;不需要指定方法名,但必须指定全类名.方法名部分第一个或最后一个字母可用*进行通配.
这么说,我有n个service类要配置事务的话,也要全部类写&lt;value&gt;****&lt;/value&gt;中,而且对于同一个类,不同的方法要配PROPAGATION_REQUIRED,readOnly;PROPAGATION_SUPPORT等,同一个类就好好几个&lt;value&gt;***&lt;/value&gt;,
又还要写个另外n个bean定义service,这些定义提供给action 调用....  还是beannameAutoproxy好很多哦
22 楼 hongliang 2006-03-23  
我就是这个意思。而我所希望的是类名也不指定。所以我只能用transactionAttributes叻,不过也没什么不好的地方:)
21 楼 nihongye 2006-03-23  
引用
transactionAttributeSource好像是必须要指明方法名才行,而transactionAttributes则不需要。。。
transactionAttributeSource
使用&lt;value&gt;xx.xx*=PRO...&lt;/value&gt;这种写法,spring使用TransactionAttributeSourceEdtior对value进行处理,创建出一个MethodName..AttributeSource实例来;不需要指定方法名,但必须指定全类名.方法名部分第一个或最后一个字母可用*进行通配.
20 楼 hongliang 2006-03-23  
nihongye 写道
引用
问错叻啦,是我一开始提出的。后来我试验叻,的确不行

ok,如果使用transactionAttributeSource的话


transactionAttributeSource好像是必须要指明方法名才行,而transactionAttributes则不需要。。。
19 楼 nihongye 2006-03-23  
引用
问错叻啦,是我一开始提出的。后来我试验叻,的确不行

ok,如果使用transactionAttributeSource的话
18 楼 jkit 2006-03-23  
接口里面要定义方法的。
前面的回复
jkit.ILogic.execute*=PROPAGATION_REQUIRED


有点要注意的是:这里的自动代理是针对方法的,而不是针对类型的。
这个接口也并非是为了配置这个事务而特意做的,而是把已经存在的接口直接拿过来用,以实现在不改变原有代码的基础上添加事务。
17 楼 hongliang 2006-03-23  
Feiing 写道

btw, 问一下 jkit, 你的那个标志性接口不用定义任何方法吗, 我试了
 somepackage.IService.* =   PROPAGATION_REQUIRED
貌似不行


问错叻啦,是我一开始提出的。后来我试验叻,的确不行,Spring AOP会去找这个接口定义的方法,空接口是不允许的,因为它找不到任何Method。

最后的方案是使用BeanNameAutoProxyCreator,还是不要空的接口,配置transactionAttributes而不是transactionAttributeSource。像这样:

    <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
        <property name="transactionManager" ref="transactionManager"/>?
		<property name="transactionAttributes">
			<props>
				<prop key="*">PROPAGATION_REQUIRED</prop>
				<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
			</props>
		</property>
    </bean>


详见Wiki:
http://www.iteye.com/pages/viewpage.action?pageId=1314
16 楼 Feiing 2006-03-23  
稍微总结一下,  两种实现方案

1. 使用 DefaultAdvisorAutoProxyCreator ,  需要事务控制的类实现一个标志性接口

2. 使用 BeanNameAutoProxyCreator, 需要事务控制的 bean 声明时名称需要满足一定规则, 如 xxxManager, xxxService

至于孰优孰劣,就见仁见智了:lol:

btw, 问一下 jkit, 你的那个标志性接口不用定义任何方法吗, 我试了
 somepackage.IService.* =   PROPAGATION_REQUIRED
貌似不行
15 楼 jkit 2006-03-21  
nihongye 写道
引用
IService接口不含任何东西,只是用来做标志。

直接使用beanname做标记,省下实现IService.transactionattribute就用find*...


这种方式虽然省下了IService,但是必须多出一个命名规约。
这种小的规约一旦多了,就容易遗忘,而且无法检查其正确性,到最后都不知道是怎么死的!
所以接口还是必要的。而且多实现一个接口似乎不费事吧?
14 楼 hongliang 2006-03-21  
Feiing 写道

1. 用 DefaultAdvisorAutoProxyCreator 实现 autoProxy, 相比 BeanNameAutoProxyCreator 应该是来的更简洁,  哪些 bean 需要事务管理, 哪些不需要, 是在 TransactionInterceptor 中的transactionAttributeSource 中定义的,
   TransactionInterceptor 只会管理定义了的 bean, 这一点可以看一下 TransactionInterceptor 的代码,    所以就不必在BeanNameAutoProxyCreator  中声明.


这个是跟后面那个IService结合起来用的。这样就不用每加一个Service都要还去改transactionAttributeSource那个地方了

Feiing 写道

2. 用一个标志性接口 IService 来进一步减少配置量的确是一个好办法, 但是缺点是增加了侵入性, 并且个人感觉这个接口叫
   TransactionAware 似乎更为合适


nihongye的做法连这个接口都不需要了。。。。见上面:)
13 楼 partech 2006-03-21  
nihongye 写道
引用
挑衅一下 Very Happy
如果使用UnitOfWork,结合一个DomainLifeCycle的Aspect。
Spring的事务配置,就可以扔到垃圾箱里去了。
想当初被MS的COM+...MTS弄得很惨,效率极其低下,俺再也不上这个当了。

有这么神奇,赶紧上example.板凳ing

赫赫,就不打搅你们了。
回头,俺会开专门的帖子,讨论这个问题的。
12 楼 Feiing 2006-03-21  
呵呵, 想不到大家反响这么激烈, 我说一下自己的想法

1. 用 DefaultAdvisorAutoProxyCreator 实现 autoProxy, 相比 BeanNameAutoProxyCreator 应该是来的更简洁,  哪些 bean 需要事务管理, 哪些不需要, 是在 TransactionInterceptor 中的transactionAttributeSource 中定义的,
   TransactionInterceptor 只会管理定义了的 bean, 这一点可以看一下 TransactionInterceptor 的代码,    所以就不必在BeanNameAutoProxyCreator  中声明.

2. 用一个标志性接口 IService 来进一步减少配置量的确是一个好办法, 但是缺点是增加了侵入性, 并且个人感觉这个接口叫
   TransactionAware 似乎更为合适
 
3. 说到事务控制, 其实我的项目是放在 Action 做的, 可能要被鄙视了, 我们用 xwork Interceptor 实现, 再加上 webwork
   &lt;default-interceptor-ref name="defaultStack" /&gt; 的功能, 基本上完全不用再管事务, 当然策略只能是 PROPAGATION_REQUIRED 了
11 楼 nihongye 2006-03-21  
引用
挑衅一下 Very Happy
如果使用UnitOfWork,结合一个DomainLifeCycle的Aspect。
Spring的事务配置,就可以扔到垃圾箱里去了。
想当初被MS的COM+...MTS弄得很惨,效率极其低下,俺再也不上这个当了。

有这么神奇,赶紧上example.板凳ing
10 楼 hongliang 2006-03-21  
nihongye 写道
引用
IService接口不含任何东西,只是用来做标志。

直接使用beanname做标记,省下实现IService.transactionattribute就用find*...


原来可以这样啊。。。:idea:
9 楼 partech 2006-03-21  
挑衅一下
如果使用UnitOfWork,结合一个DomainLifeCycle的Aspect。
Spring的事务配置,就可以扔到垃圾箱里去了。
想当初被MS的COM+...MTS弄得很惨,效率极其低下,俺再也不上这个当了。
8 楼 nihongye 2006-03-21  
引用
IService接口不含任何东西,只是用来做标志。

直接使用beanname做标记,省下实现IService.transactionattribute就用find*...
7 楼 hongliang 2006-03-21  
完整版来叻!!

配置Spring,针对Service层的bean做事务处理,以往的做法是这样:
<bean id="txProxyTemplate" abstract="true" 
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
    <property name="transactionManager">
        <ref bean="transactionManager"/>
    </property> 
    <property name="transactionAttributes"> 
        <props>
            <prop key="find*">PROPAGATION_REQUIRED, readOnly</prop> 
            <prop key="*">PROPAGATION_REQUIRED</prop> 
        </props> 
    </property> 
</bean> 

<bean id="userManager" parent="txProxyTemplate"> 
    <property name="target"> 
        <bean class="some.package.UserManagerImpl"> 
            <property name="userDAO"><ref bean="userDAO"/></property> 
        </bean> 
    </property> 
</bean> 



以后,如果增加新的Service/Manager,则XML配置的增量是这一段:
<bean id="someOtherManager" parent="txProxyTemplate"> 
    <property name="target"> 
        <bean class="some.package.someOtherManagerImpl"> 
        </bean> 
    </property> 
</bean> 


上面说的是老的做法,比较传统。缺点是增量比较大,配置起来copy&paste让人觉得不太爽,比较臃肿。

下面的是Feiing给出的更好的方案,我有一些修改:

<beans> 
        <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA); --> 
    <bean id="transactionManager"           class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
          <property name="sessionFactory"> 
              <ref bean="sessionFactory"/> 
          </property> 
    </bean>        
        
        <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> 
            <property name="transactionManager" ref="transactionManager"/> 
            <property name="transactionAttributes">
                <props>
                    <prop key="*">PROPAGATION_REQUIRED</prop>
                    <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
                </props>
            </property>
        </bean> 
        
        <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> 
                <property name="beanNames">
                    <value>*Service,*Manager</value>
                </property>
                <property name="interceptorNames"> 
                        <list> 
                                <value>transactionInterceptor</value> 
                                <!-- 
                                此处增加新的Interceptor
                                --> 
                        </list> 
                </property> 
        </bean> 

        <bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor"> 
          <property name="transactionInterceptor" ref="transactionInterceptor"/> 
        </bean> 


        <bean id="userManager" class="some.package.UserManagerImpl" autoWire="byName"/>
                
</beans> 


以后每次的增量是这一段:
        <bean id="userManager" class="some.package.UserManagerImpl" autoWire="byName"/>


跟配置普通bean的方法一样,非常简洁、直观。对现有的Service接口也无须任何修改

我把Feiing的transactionAttributesSource改成叻transactionAttributes,并且将DefaultAdvisorAutoProxyCreator改成了BeanNameAutoProxyCreator,我觉得毕竟不是context下的每个bean都需要事务,只要在Service层做AOP就可以叻。

和Robbin一致认为,Feiing的做法非常可取,因为它分离叻XML配置文件关注点
6 楼 nihongye 2006-03-21  
引用
确实是一个好贴,不过我却有点忧虑。spring现在被用得越来越邪乎了,xml配置文件简直已经到了奇技淫巧的地步了,仿佛许多隐而不宣的武林秘籍,掌握了这些xml配置段,就无敌了。唉!


没这么夸张
使得bean注入简捷的autowire,使得创建proxy简捷的autoproxy(实现有两个,一个是DefaultAdvisorAutoProxyCreator,BeanNameAutoProxyCreator).
另外一些奇技淫巧可以查下实现了BeanPostProcessor接口的类.
5 楼 hongliang 2006-03-21  
明白叻,只要按照普通的配置bean的方法配置UserManager就行叻。

的确是个非常好的方法!!

相关推荐

    spring事务配置的五种方式

    ### Spring事务配置的五种方式详解 #### 一、引言 在企业级应用开发中,事务处理是非常重要的一部分,特别是在涉及多个数据库操作时。Spring框架提供了强大的事务管理功能,支持编程式和声明式两种事务处理方式。...

    Spring 事务代理配置

    最后,需要将事务拦截器应用到具体的目标类上,通常是在`aop:config`标签下配置切入点和增强,或者通过`@Transactional`注解来简化配置。 ```xml (* com.example.service.*.*(..))"/&gt; ``` 或者使用`@...

    Spring事务管理开发必备jar包

    本资源包提供了进行Spring事务管理开发所需的所有关键库,包括框架基础、核心组件、AOP(面向切面编程)支持、日志处理、编译工具以及与数据库交互的相关jar包。下面将对这些知识点进行详细解释: 1. **Spring框架*...

    spring事务案例分析.zip

    7. **案例分析**:"SPRING事务管理案例分析.docx"很可能包含了具体的项目实例,详细讲解了如何在Spring项目中配置和使用事务管理,以及如何解决实践中遇到的问题。而"studyspring"可能是源代码目录,包含了实现这些...

    spring 事务传播 demo

    在Java后端开发中,Spring的事务管理机制大大简化了事务控制,使得开发者可以更专注于业务逻辑,而不用关心底层事务的管理。通过声明式事务管理,我们只需在方法上添加@Transactional注解,而无需编写手动的try-...

    spring声明事务的配置

    此外,Spring Boot简化了Spring应用的启动和配置,包括事务管理,使得在现代项目中使用声明式事务更加便捷。 总的来说,Spring声明式事务管理提供了一种强大且灵活的方式来控制事务的边界,使得事务管理与业务逻辑...

    spring事务详解

    在实际应用中,Spring事务管理的配置和使用需要注意以下几个方面: - 事务传播行为:定义了事务在遇到已有事务时的行为模式,例如是否加入当前事务、新建一个事务等。 - 事务隔离级别:定义了事务的隔离水平,例如...

    Spring事务管理配置

    在深入探讨Spring事务管理配置之前,我们先简要回顾一下Spring框架的核心概念。Spring是一个开源的Java平台,它提供了一套全面的编程和配置模型,旨在简化企业级应用的开发。其中,事务管理是Spring框架中的一个重要...

    实验 spring 声明事务

    Spring 提供了声明式事务管理,允许开发者在不编写事务管理代码的情况下实现事务控制,极大地简化了事务处理。 实验环境主要包括 Eclipse 或 MyEclipse 开发工具,以及 Spring 4.0 及以上版本,JDK 1.7 及以上版本...

    Spring事务五种不同的代理配置

    第一种方式需要手动配置事务规则,而第二、三种方式通过注解简化了配置,第四种方式适用于不依赖接口的情况,第五种方式则提供了最大的灵活性。在实际开发中,我们通常会选择基于注解的声明式事务管理,因为它既简洁...

    Spring事务配置的五种方式

    这种方式的优点是可以简化配置文件,但是缺点是需要了解 AOP 的机制和实现。 第三种方式:使用代理工厂 这种方式使用了 Spring 的代理工厂机制,可以将事务管理器注入到 Bean 中。这种方式的优点是可以灵活地控制...

    Spring基于XML方式配置事务

    结合上述配置,Spring会自动管理事务的开始、提交、回滚等操作,大大简化了事务管理的代码。在实际项目中,根据业务需求,我们可以灵活调整这些配置,以实现高效、安全的事务处理。 在提供的压缩包文件`Spring-JDBC...

    spring 事务基于注解模式

    Spring事务管理分为编程式和声明式两种。编程式事务管理通过编程的方式(如使用`TransactionTemplate`或直接调用`PlatformTransactionManager`)来控制事务的开始、提交、回滚等操作。而声明式事务管理则是在配置...

    Spring事务优缺点及使用详解.docx

    Spring事务管理提供了统一的事务处理模型,使得开发者无需关注具体数据库访问技术的事务细节,简化了事务控制代码,提高了代码的可读性和可维护性。无论是使用注解还是AOP配置,都能有效地管理和协调事务,确保应用...

    Spring事务详解

    本文将深入探讨Spring事务管理的概念、类型、配置方式以及在实际开发中的应用。 首先,我们要理解什么是事务。事务是数据库操作的基本单元,它确保一组数据库操作要么全部成功,要么全部失败。事务有四大特性,即...

    Spring的事务管理小案例

    在本文中,我们将深入探讨Spring框架中的事务管理。Spring是一个广泛应用的Java企业级应用开发框架,它提供...如果你想要深入了解,可以参考提供的博客链接或其他相关资料,进一步学习Spring事务管理的细节和最佳实践。

    spring声明式事务配置

    根据提供的信息,我们可以深入探讨Spring框架中的声明式事务配置及其多种实现方式。声明式事务管理是一种简化事务管理的方式,它允许开发人员通过配置而非编程来指定事务边界,从而减少了代码的复杂性并提高了可维护...

    Spring 事务配置详解(多种配置方法)

    Spring 2.5引入了注解事务管理,可以直接在Service层的方法上添加@Transactional注解,简化配置。例如: ```java @Service public class UserService { @Transactional public void addUser(User user) { // ...

    spring事务管理5种方法

    本篇文章将深入探讨Spring事务管理的五种方法,旨在帮助开发者更好地理解和运用这一核心特性。 首先,我们来了解什么是事务。在数据库操作中,事务是一组逻辑操作,这些操作要么全部成功,要么全部失败,确保数据的...

Global site tag (gtag.js) - Google Analytics