Announcement Announcement Module
Collapse
No announcement yet.
AOP Declarative Transaction Management Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • AOP Declarative Transaction Management

    Hello All,

    We have currently managed to used AOP based Declarative Transaction management for all our Service method calls. Please find a sample of the Configuration File below.

    Code:
        <!-- the transactional advice (i.e. what 'happens'; see the <aop:advisor/> bean below) -->
        <tx:advice id="txAdvice" transaction-manager="txManager">
        <!-- the transactional semantics... -->
         <tx:attributes>
          <!-- all methods starting with 'get' are read-only -->
          <tx:method name="get*" read-only="true"/>
          <tx:method name="validate*" read-only="true"/>
          <!-- other methods use the default transaction settings (see below) -->
          <tx:method name="*" read-only="false" rollback-for="ApplicationException"/>
         </tx:attributes>
        </tx:advice>
      <aop:config>
        <aop:pointcut id="allServiceOperation" expression="execution(* com.paz.appln.services..*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="allServiceOperation"/>
      </aop:config>
    
       <!-- similarly, don't forget the PlatformTransactionManager -->
        <bean id="txManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager">
        </bean>
    This configuration works as long as the services are called with package structure "com.paz.appln.services" and any services underneath.

    Problem:
    I have a Wrapper Service around all the existing service which also has the same package structure: "com.paz.appln.services". I use this Wrapper Service as a Facade to call the individual services to perform Database operations under a single Transaction. Consider my wrapper invokes Service1, Service2, Service3 & Service4. If Service1 completes successfully with proper database operation and Service2 fails during its database operation, the Transaction doesnt seem to roll back as expected.

    I tried some pointers from various books and forum threads like adding propogation to be "REQUIRED" in the configuration:

    Code:
    <tx:method name="*" propagation="REQUIRED" read-only="false" rollback-for="ApplicationException"/>
    but none worked

    Can someone help me to understand what mistake I am doing?

    Note: When I refer "services", they are tiered POJO Classes exposiong Business methods. We do not use EJBs or any other Technologies.

    Thanks and regards,
    Paz

  • #2
    How are you configuring and calling your services?

    Comment


    • #3
      Declarative Transaction Management

      Hello,

      My Services are configured as :

      Code:
      <bean id="commissionDAO" class="com.paz.appln.dao.impl.CommissionDAOImpl"/>
      <bean id="commissionService" class="com.paz.appln.services.impl.CommissionDetailServiceImpl"/>
      If you see in the above config, the package name is com.paz.appln.

      I use Spring Application Context to instantiate the Beans based on the Bean IDs: commissionService & commissionDAO...

      Thanks,
      Paz

      Comment


      • #4
        That still doesn't answer the full question HOW are you accessing those services...

        Comment


        • #5
          Declarative Transaction Management

          Hello mdeinum,

          I dont think I understood your question. I use Application Context

          Code:
          CommissionService service = (CommissionService ) appContext.getBean ("commissionService");
          service.createCommission ();
          Do I have to go through "org.springframework.transaction.interceptor.Trans actionProxyFactoryBean"???

          Thanks and Regards,
          Paz

          Comment


          • #6
            No that is being handled for you...

            I'm hinting on your facade how is that accessed and how is that configured!

            Comment


            • #7
              Declarative Transaction Management

              Hello mdeinum,

              To give more details, our facade is a Spring HTTP Invoker Type Bean configured as:

              Code:
              <bean id="newBusinessRemoteService" class="com.paz.appln.services.remote.impl.NewBusinessRemoteServiceImpl"/>    
                  <bean name="/NewBusinessRemoteService" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
                      <property name="service"><ref bean="newBusinessRemoteService"/></property>
                      <property name="serviceInterface"><value>com.paz.appln.services.remote.NewBusinessRemoteService</value></property>
                  </bean>
              We access the Facade using the ApplicationContext again.

              Code:
              NewBusinessRemoteService service = (NewBusinessRemoteService) appContext.getBean ("newBusinessRemoteService");
              service.createApplication();

              Thanks,
              Paz

              Comment


              • #8
                Why do you always get the beans from the context and don't simply inject them? Next to that how do you get the appContext property? Is it injected (i.e. beans ApplicationContextAware) or do you create a new one new ApplicationContext each time?

                Also make sure the transaction configuration is loaded in the SAME application context as your services if it is in a parent context beans don't get adviced.

                Comment


                • #9
                  Transactional Rollbacks

                  Hi, are you sure that the exceptions thrown are caught by your rollback? Check the winning rollback rule and sequence of events: what the transaction synchronization is doing from call 1 to call 2, etc. Try setting propagation to REQUIRES_NEW to see whether the synchronizer pauses the first to start the second transaction and check your pointcut for the wrapper. I'm about to set up a service wrapper myself so please post your working solution
                  Last edited by Helena; Feb 19th, 2008, 12:51 AM.

                  Comment


                  • #10
                    Declarative Transaction Management

                    Hello All,

                    I think I found the missing link for this Transaction not being managed. I would ask your opinion on what I have found and applied to fix the problem.

                    My Facade which I instantiate using Spring Bean Factory was not transaction aware. So I added a Transaction Proxy Factory Bean which made it transaction aware and made all services to be under a single transaction.

                    Code:
                        <!--
                            #### Remote Service Impl Bean Definition 3 ####
                          -->
                        <bean id="newBusinessRemoteServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
                            <property name="transactionManager"><ref bean="remoteTxManager"/></property>
                            <property name="target"><ref bean="newBusinessRemoteService"/></property>
                            <property name="transactionAttributes">
                                <props><prop key="submit*">PROPAGATION_REQUIRED</prop></props>
                            </property>
                        </bean>
                    
                        <bean id="newBusinessRemoteService" class="com.paz.appln.services.remote.impl.NewBusinessRemoteServiceImpl"/>    
                        <bean name="/NewBusinessRemoteService" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
                            <property name="service"><ref bean="newBusinessRemoteServiceProxy"/></property>
                            <property name="serviceInterface"><value>com.paz.appln.services.remote.NewBusinessRemoteService</value></property>
                        </bean>
                        
                        <!--
                            Create a WebLogic JTA Transaction Manager Bean. This is a replica of what is available in Nova
                            because these files get loaded before Nova Transaction manager loads
                        -->
                        <bean id="remoteTxManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager">
                            <property name="transactionManagerName" value="javax.transaction.TransactionManager"/>
                        </bean>
                    By changing my configurations, it started to roll back in case if one of the services had any DB Exceptions from the Database.

                    Correct me if my understanding is correct.


                    Thanks,
                    Paz

                    Comment


                    • #11
                      I don't think you need to declare that, just set the transactional advice

                      Code:
                      <aop:config>
                              <aop:pointcut id="dataAccessOperation"
                                            expression="execution(* com.foo.infrastructure.SystemArchitecture.dataAccessOperation())"/>
                      <aop:advisor advice-ref="txAdvice" pointcut-ref="dataAccessOperation"/>
                          </aop:config>
                      or an interface implemented by all dao's which is proxied:
                      Code:
                      <aop:config>
                              <aop:pointcut id="dataAccessOperation"
                                            expression="this(com.foo.service.MyServiceInterface))"/>
                      <aop:advisor advice-ref="txAdvice" pointcut-ref="dataAccessOperation"/>
                          </aop:config>
                      Last edited by Helena; Feb 19th, 2008, 01:13 AM.

                      Comment

                      Working...
                      X