企业管理及信息化解决方案;--因为专注,所以专业!
客服热线:028-86272612
成都蓝源 -> > EDP资讯 -> 详细内容
Lanyo EDP中的事务问题
时间: 2011-12-07    来源:

先来回顾一下在传统SSH项目中的事务控制策略。在传统SSH中,使用org.springframework.orm.hibernate3.support.OpenSessionInViewFilter来打开session,然后使用声明式事务配置,不管是采用XML的或者是Annotation的,事务边界都开在service服务上。

    但是在EDP的应用中,情况会发生一些变化。首先是事务。在默认情况下,EDP中并没有使用传统的opensessioninview+aop transcation的方式,我们可以发现,在web.xml中,并没有openSessionInViewFilter的配置,那ejs是怎么解决lazy load的问题的呢?另一个问题,在application.xml中或者任何的service.xml中,也都没有看到有对servicetranscation的拦截,那ejs中又是怎么控制事务的呢?打开open-spring-transcation.xml文件,我们可以发现,ejs将一个tx:advice开在了DefaultRequestProceesorprocess的方法上。DefaultRequestProceesorprocess方法是包裹了整个action的执行、结果处理和错误处理(在jweb中,默认即是使用Velocity来处理视图合成的)。这样一来,ejs中的应用spring将在DefaultRequestProcessor的开始阶段(Action开始之前)就打开一个统一的事务,在整个action处理完成之后,统一提交事务,也不会出现lazy load的问题。一个简单的示意图:

可以看到,事务的范围并不是直接控制在action上的,而是横跨了整个jweb的处理范围。这样处理的好处:

1,简单:可以看到这种处理方式非常的简单,在80%的时间内,不需要特别的为service开启额外的事务控制,

2,统一:不需要额外的XML或者annotation,或者openSessionInView

只要在Action中的业务足够短(避免事务的执行之间过长,造成大量的死锁可能),这样处理能很简化的处理事务的问题。但这样在并发量过大的情况下还是会有很多并发问题。要让基于EDP的应用支持正常的错误处理和事务,这点使用标准的SSH方式即可。

现在就将EDP切换到标准SSH事务和Lazy Load处理,并且支持JWEB的错误处理方式。其实这个过程还是非常简单的,在这个过程中,我还会讨论一些其他问题。

 

1,去掉在DefaultRequestProcessor上面的事务配置,在EDPresources/application.xml中去掉:

    import resource="classpath:/com/easyjf/core/open-spring-transaction.xml"

2,在application-core-2.0.jar中的com.lanyotech.core/applicationBeans.xml中已经定义了对所有application-core-2.0serviceXML声明式事务配置,抽取如下:

<tx:advice id="SystemRegionAdvice" transaction-manager="transactionManager">

  <tx:attributes>

   <tx:method name="add*" propagation="REQUIRES_NEW"/>

   <tx:method name="*" propagation="REQUIRED" read-only="true" />

  </tx:attributes>

</tx:advice>


<tx:advice id="txAdvice" transaction-manager="transactionManager">

  <tx:attributes>

   <tx:method name="*" propagation="REQUIRED" />

   <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>

  </tx:attributes>

</tx:advice>


<aop:config>

  <aop:pointcut id="SystemRegionMethods"              expression="execution(* com.lanyotech.core.service.ISystemRegionService.*(..))"/>

  <aop:pointcut id="applicationCoreServiceMethods"

expression="execution(* com.lanyotech.core.service.*.*(..))" />

  <aop:pointcut id="applicationSecurityServiceMethods"

expression="execution(* com.lanyotech.security.service.*.*(..))" />

  <aop:advisor advice-ref="SystemRegionAdvice" pointcut-ref="SystemRegionMethods"/>

  <aop:advisor advice-ref="txAdvice" pointcut-ref="applicationCoreServiceMethods" />

  <aop:advisor advice-ref="txAdvice" pointcut-ref="applicationSecurityServiceMethods" />

</aop:config>

3,在web.xml中添加OpenSessionInViewFilter

<filter>

       <filter-name>openSessionInView</filter-name>

       <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>

    </filter>


<filter-mapping>

       <filter-name>openSessionInView</filter-name>

       <url-pattern>/*</url-pattern>

    </filter-mapping>

4,到此,事务的配置已经切换完成。自己的项目中的service可以使用XML的,或者使用annotation的声明式事务配置都可以。当然为了让EDP中的示例和chat能正常运行,需要增加以下XML事务配置:

<aop:config>

       <aop:pointcut id="riaSampleService"      expression="execution(* com.lanyo.ria.samples.service..*.*(..))"/>

       <aop:pointcut id="riaService"

expression="execution(* com.lanyo.ria.service.*.*(..))" />

       <aop:advisor advice-ref="txAdvice" pointcut-ref="riaSampleService" />

       <aop:advisor advice-ref="txAdvice" pointcut-ref="riaService" />

    </aop:config>

 

<aop:config>

       <aop:pointcut id="chatService"

expression="execution(* com.lanyotech.chat.service.*.*(..))" />

       <aop:advisor advice-ref="txAdvice" pointcut-ref="chatService" />

    </aop:config>

 



3.62K