论坛首页 Java企业应用论坛

Spring 事务简化配置

浏览 67730 次
该帖已经被评为精华帖
作者 正文
   发表时间:2006-03-23  
nihongye 写道
引用
问错叻啦,是我一开始提出的。后来我试验叻,的确不行

ok,如果使用transactionAttributeSource的话


transactionAttributeSource好像是必须要指明方法名才行,而transactionAttributes则不需要。。。
0 请登录后投票
   发表时间:2006-03-23  
引用
transactionAttributeSource好像是必须要指明方法名才行,而transactionAttributes则不需要。。。
transactionAttributeSource
使用<value>xx.xx*=PRO...</value>这种写法,spring使用TransactionAttributeSourceEdtior对value进行处理,创建出一个MethodName..AttributeSource实例来;不需要指定方法名,但必须指定全类名.方法名部分第一个或最后一个字母可用*进行通配.
0 请登录后投票
   发表时间:2006-03-23  
我就是这个意思。而我所希望的是类名也不指定。所以我只能用transactionAttributes叻,不过也没什么不好的地方:)
0 请登录后投票
   发表时间:2006-03-23  
nihongye 写道
引用
transactionAttributeSource好像是必须要指明方法名才行,而transactionAttributes则不需要。。。
transactionAttributeSource
使用<value>xx.xx*=PRO...</value>这种写法,spring使用TransactionAttributeSourceEdtior对value进行处理,创建出一个MethodName..AttributeSource实例来;不需要指定方法名,但必须指定全类名.方法名部分第一个或最后一个字母可用*进行通配.
这么说,我有n个service类要配置事务的话,也要全部类写<value>****</value>中,而且对于同一个类,不同的方法要配PROPAGATION_REQUIRED,readOnly;PROPAGATION_SUPPORT等,同一个类就好好几个<value>***</value>,
又还要写个另外n个bean定义service,这些定义提供给action 调用....  还是beannameAutoproxy好很多哦
0 请登录后投票
   发表时间:2006-03-24  
我觉得当然是用BeanNameAutoProxyCreator方便,不然每次加service都还要跑去改transactionAttributeSource太麻烦叻
0 请登录后投票
   发表时间:2006-03-27  
这样配置,在单独测试usermanager时,没有问题.
但当放到tomcat中,通过action调用usermanager时却出现异常,用以前的那种配法没有出现问题.
Exception:
2006-03-27 12:35:21,377 ERROR [com.opensymphony.webwork.dispatcher.DispatcherUtils] - Could not execute action
java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method);
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39);
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25);
	at java.lang.reflect.Method.invoke(Method.java:585);
	at com.opensymphony.xwork.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:353);
	at com.opensymphony.xwork.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:208);
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:182);
	at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:32);
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:180);
	at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:32);
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:180);
	at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:32);
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:180);
	at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:32);
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:180);
	at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:32);
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:180);
	at com.opensymphony.xwork.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:94);
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:180);
	at com.opensymphony.xwork.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:94);
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:180);
	at com.opensymphony.xwork.DefaultActionProxy.execute(DefaultActionProxy.java:119);
	at com.opensymphony.webwork.dispatcher.DispatcherUtils.serviceAction(DispatcherUtils.java:183);
	at com.opensymphony.webwork.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:182);
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202);
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173);
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213);
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178);
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126);
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105);
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107);
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148);
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869);
	at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:667);
	at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527);
	at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80);
	at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684);
	at java.lang.Thread.run(Thread.java:595);
Caused by: java.lang.StackOverflowError
	at java.lang.System.identityHashCode(Native Method);
	at java.util.IdentityHashMap.hash(IdentityHashMap.java:283);
	at java.util.IdentityHashMap.get(IdentityHashMap.java:313);
	at org.springframework.aop.framework.HashMapCachingAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(HashMapCachingAdvisorChainFactory.java:44);
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:154);
	at $Proxy1.getTransaction(Unknown Source);
	at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:217);
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:89);
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144);
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:174);
	at $Proxy1.getTransaction(Unknown Source);
......
0 请登录后投票
   发表时间:2006-03-30  
hongliang 写道
完整版来叻!!
下面的是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配置文件关注点


受hongliang启发,我现在就用这个方法,但是发现一个Bug。里面代理匹配的名字有*Manager,就是想匹配所有的ManagerObject。但是好像没有注意到,这样配置会把transactionManager也匹配上,然后定义的是find以外的方法都是要事务的。也就说transactionManager执行getTransaction的时候还会要事务,然后就是死循环,造成溢出。。

我解决的办法就是transactionManager改称transactionManagerHibernate。这么做的时候一定要注意名字的问题。别一不小心,把一个不相关的东东给弄进来的。。。

对了,加Acegi的时候有很多*Manager,打算想一个比较好名字匹配。。
0 请登录后投票
   发表时间:2006-03-30  
差沙 写道
受hongliang启发,我现在就用这个方法,但是发现一个Bug。里面代理匹配的名字有*Manager,就是想匹配所有的ManagerObject。但是好像没有注意到,这样配置会把transactionManager也匹配上,然后定义的是find以外的方法都是要事务的。也就说transactionManager执行getTransaction的时候还会要事务,然后就是死循环,造成溢出。。

我解决的办法就是transactionManager改称transactionManagerHibernate。这么做的时候一定要注意名字的问题。别一不小心,把一个不相关的东东给弄进来的。。。

对了,加Acegi的时候有很多*Manager,打算想一个比较好名字匹配。。


啊!!!这个我还真的没有注意到,因为我所有的Service层都是*Service,我从来不用*Manager的。。。怪不得我的没问题,
0 请登录后投票
   发表时间:2006-03-30  
hongliang 写道

啊!!!这个我还真的没有注意到,因为我所有的Service层都是*Service,我从来不用*Manager的。。。怪不得我的没问题,


关键是你的事务管理对象的名字是*Manager呀,怎么会没有问题出现呢?难道是我的人品问题??
0 请登录后投票
   发表时间:2006-03-30  
差沙 写道
hongliang 写道

啊!!!这个我还真的没有注意到,因为我所有的Service层都是*Service,我从来不用*Manager的。。。怪不得我的没问题,


关键是你的事务管理对象的名字是*Manager呀,怎么会没有问题出现呢?难道是我的人品问题??


我上面给的代码写的是*Service,*Manager,是为叻迎合大家的口味 我自己不用*Manager,只有*Service 
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics