Announcement Announcement Module
Collapse
No announcement yet.
how to override declarative transaction setting Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • how to override declarative transaction setting

    In our project, there over 100 business service objects. Since all the BOs only default transaction control, we use something like bellow to implement the transaction management for all these BOs.
    <tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
    <tx:method name="*"/>
    </tx:attributes>
    </tx:advice>

    <aop:config>
    <aopointcut id="serviceOperation" expression="execution( *Service.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation"/>
    </aop:config>


    Now, since a new requirement, we need to change transaction setting of one of the BO (we want to apply REQUIRE_NEW to one of the methods of that BO).

    When we were using session bean provided by Websphere, this issue can be solved easily since the default setting for all session beans are REQUIRED. The only thing I have to amend the default configuration in the ejb xml file. However, how can I do the same thing in Spring?

    I thing it would not work if I create another pointcut for the method need REQUIRED_NEW, since it just create another advisor for that method.

    Now, we have workaround solution for this issue, we change the class name of that BO and create another pointcut and advice for it. This approach works but it violate our naming convention and it make this BO so odd in the workspace. So we are still looking for other better solution. We hope we can override the default transaction setting of that BO without any java source modification and significant config modification. Any body have any idea?

  • #2
    If the name of the method you want to change the propagation mode is unique, you can do the following:

    Code:
    <tx:advice id="txAdvice" transaction-manager="txManager">
    	<tx:attributes>
    		<tx:method name="*"/>
    		<tx:method name="methodName" propagation="REQUIRES_NEW"/>
    	</tx:attributes>
    </tx:advice>

    Comment


    • #3
      fvitorc:

      In your approach, there are two tx:method match the method with name "methodName", how the container know which propagation should be used?

      Comment


      • #4
        I believe that Spring will try to match the most specific one. In this case, 'methodName'.
        You can turn logging in debug level for package 'org.springframework.orm.jpa' and see it for yourself what is actually happening.

        You should see something like this in your log depending on pattern used for the output:
        Code:
        05/12/2008 17:16:45 JpaTransactionManager getTransaction
        DEBUG: Using transaction object [JpaTransactionManager JpaTransactionObject]
        05/12/2008 17:16:45 JpaTransactionManager getTransaction
        DEBUG: Creating new transaction with name [MyService.methodName]: REQUIRES_NEW,ISOLATION_DEFAULT
        05/12/2008 17:16:45 JpaTransactionManager doBegin
        DEBUG: Opened new EntityManager [EntityManagerImpl] for JPA transaction
        05/12/2008 17:16:45 JpaTransactionManager triggerBeforeCommit
        DEBUG: Triggering beforeCommit synchronization
        05/12/2008 17:16:45 JpaTransactionManager triggerBeforeCompletion
        DEBUG: Triggering beforeCompletion synchronization
        05/12/2008 17:16:45 JpaTransactionManager processCommit
        DEBUG: Initiating transaction commit
        05/12/2008 17:16:45 JpaTransactionManager doCommit
        DEBUG: Committing JPA transaction on EntityManager [EntityManagerImpl]
        05/12/2008 17:16:46 JpaTransactionManager triggerAfterCommit
        DEBUG: Triggering afterCommit synchronization
        05/12/2008 17:16:46 JpaTransactionManager triggerAfterCompletion
        DEBUG: Triggering afterCompletion synchronization
        05/12/2008 17:16:46 JpaTransactionManager doCleanupAfterCompletion
        DEBUG: Closing JPA EntityManager [EntityManagerImpl] after transaction
        05/12/2008 17:16:46 EntityManagerFactoryUtils closeEntityManager
        DEBUG: Closing JPA EntityManager
        The important thing to note here is the second log output, where it says which propagation and isolation mode it is using. Try it yourself and post a reply saying if it works.

        People usually do this for read only methods:
        Code:
        <tx:advice id="txAdvice" transaction-manager="txManager">
        	<tx:attributes>
        		<tx:method name="*" propagation="REQUIRED" />
        		<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
        		<tx:method name="list*" propagation="SUPPORTS" read-only="true" />
        	</tx:attributes>
        </tx:advice>
        If it doesn't work, than it is because Spring tries to match the first one in the list, so you can put the most specific ones first, like this:
        Code:
        <tx:advice id="txAdvice" transaction-manager="txManager">
        	<tx:attributes>
        		<tx:method name="methodName" propagation="REQUIRES_NEW"/>
        		<tx:method name="*"/>
        	</tx:attributes>
        </tx:advice>
        Hope this helps.
        Happy new year.

        Comment

        Working...
        X