Results 1 to 3 of 3

Thread: Transaction Behaviour

  1. #1
    Join Date
    Aug 2004
    Location
    San Francisco
    Posts
    423

    Default Transaction Behaviour

    Hi,

    I'm observing some strange transaction behaviour and cannot for the life of me figure out what I'm doing wrong.

    I've two methods, methodOne and methodTwo. Both have transaction attributes and methodTwo calls methodOne. It appears that the attributes on methodOne are ignored in this situation. Calling methodOne on its own appears fine.

    Looking at the log traces there is a call,

    DEBUG [org.springframework.transaction.interceptor.Transa ctionInterceptor] - Getting transaction for method 'methodTwo' in class [test.TransactionTestI]

    but this never happens for methodOne, even though as I mentioned, methodOne is called by methodTwo.

    Here is an application context from a very simple test situation I set up. In reality, I'm using source code annotations but see the same behaviour.

    Code:
    <bean id="transactionTestTarget" class="test.TransactionTest" />
    	
    	<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
    		
    		<property name="transactionManager"><ref bean="transactionManager"/></property>
    		<property name="transactionAttributeSource">
            	<value>
    				test.TransactionTestI.methodOne=PROPAGATION_NEVER
    				test.TransactionTestI.methodTwo=PROPAGATION_REQUIRED
    			</value>
    			
    		</property>
    	</bean>
    	
    	<bean id="transactionTest" class="org.springframework.aop.framework.ProxyFactoryBean">
    		<property name="proxyInterfaces">
    			<value>test.TransactionTestI</value>
    		</property>
    		<property name="target"><ref local="transactionTestTarget"/></property>
    		<property name="interceptorNames">
    			<list>
    				<value>transactionInterceptor</value>
    			</list>
    		</property>
    	</bean>
    with the transactionManager being a HibernateTransactionManager, although this basic test does not access Hibernate.

    The behaviour I'd expect in the above case of attributes is that an exception would be thrown when calling methodOne due to the PROPAGATION_NEVER. It isn't thrown.

    Has anyone any ideas what maybe causing this problem, or am I wrong in my assumption about the behaviour of one transactioned method calling another?

    Here's a log trace with pertinant logging turned on:
    Code:
    INFO &#91;org.springframework.orm.hibernate.LocalSessionFactoryBean&#93; - Building new Hibernate SessionFactory
     INFO &#91;org.springframework.orm.hibernate.HibernateTransactionManager&#93; - Using DataSource &#91;org.apache.commons.dbcp.BasicDataSource@f6f1b6&#93; from Hibernate SessionFactory for HibernateTransactionManager
    DEBUG &#91;org.springframework.transaction.interceptor.MethodMapTransactionAttributeSource&#93; - Adding transactional method &#91;test.TransactionTestI.methodTwo&#93; with attribute &#91;PROPAGATION_REQUIRED,ISOLATION_DEFAULT&#93;
     INFO &#91;org.springframework.transaction.interceptor.MethodMapTransactionAttributeSource&#93; - Adding transactional method &#91;public abstract void test.TransactionTestI.methodTwo&#40;&#41;&#93; with attribute &#91;PROPAGATION_REQUIRED,ISOLATION_DEFAULT&#93;
    DEBUG &#91;org.springframework.transaction.interceptor.MethodMapTransactionAttributeSource&#93; - Adding transactional method &#91;test.TransactionTestI.methodOne&#93; with attribute &#91;PROPAGATION_NEVER,ISOLATION_DEFAULT&#93;
     INFO &#91;org.springframework.transaction.interceptor.MethodMapTransactionAttributeSource&#93; - Adding transactional method &#91;public abstract void test.TransactionTestI.methodOne&#40;&#41;&#93; with attribute &#91;PROPAGATION_NEVER,ISOLATION_DEFAULT&#93;
    DEBUG &#91;org.springframework.transaction.interceptor.TransactionInterceptor&#93; - Getting transaction for method 'methodTwo' in class &#91;test.TransactionTestI&#93;
    DEBUG &#91;org.springframework.orm.hibernate.HibernateTransactionManager&#93; - Using transaction object &#91;org.springframework.orm.hibernate.HibernateTransactionObject@1582a7c&#93;
    DEBUG &#91;org.springframework.orm.hibernate.HibernateTransactionManager&#93; - Creating new transaction
    DEBUG &#91;org.springframework.orm.hibernate.SessionFactoryUtils&#93; - Opening Hibernate session
    DEBUG &#91;org.springframework.orm.hibernate.HibernateTransactionManager&#93; - Opened new session &#91;net.sf.hibernate.impl.SessionImpl@a010ba&#93; for Hibernate transaction
    DEBUG &#91;org.springframework.orm.hibernate.HibernateTransactionManager&#93; - Beginning Hibernate transaction on session &#91;net.sf.hibernate.impl.SessionImpl@a010ba&#93;
    DEBUG &#91;org.springframework.transaction.support.TransactionSynchronizationManager&#93; - Bound value &#91;org.springframework.orm.hibernate.SessionHolder@149f041&#93; for key &#91;net.sf.hibernate.impl.SessionFactoryImpl@29d294&#93; to thread &#91;main&#93;
    DEBUG &#91;org.springframework.transaction.support.TransactionSynchronizationManager&#93; - Bound value &#91;org.springframework.jdbc.datasource.ConnectionHolder@1984a9d&#93; for key &#91;org.apache.commons.dbcp.BasicDataSource@f6f1b6&#93; to thread &#91;main&#93;
    DEBUG &#91;org.springframework.transaction.support.TransactionSynchronizationManager&#93; - Initializing transaction synchronization
    DEBUG &#91;test.TransactionTest&#93; - In method two
    DEBUG &#91;test.TransactionTest&#93; - In method one
    DEBUG &#91;org.springframework.transaction.interceptor.TransactionInterceptor&#93; - Invoking commit for transaction on method 'methodTwo' in class &#91;test.TransactionTestI&#93;
    DEBUG &#91;org.springframework.orm.hibernate.HibernateTransactionManager&#93; - Triggering beforeCommit synchronization
    DEBUG &#91;org.springframework.orm.hibernate.HibernateTransactionManager&#93; - Triggering beforeCompletion synchronization
     INFO &#91;org.springframework.orm.hibernate.HibernateTransactionManager&#93; - Initiating transaction commit
    DEBUG &#91;org.springframework.orm.hibernate.HibernateTransactionManager&#93; - Committing Hibernate transaction on session &#91;net.sf.hibernate.impl.SessionImpl@a010ba&#93;
    DEBUG &#91;org.springframework.orm.hibernate.HibernateTransactionManager&#93; - Triggering afterCompletion synchronization
    DEBUG &#91;org.springframework.transaction.support.TransactionSynchronizationManager&#93; - Clearing transaction synchronization
    DEBUG &#91;org.springframework.transaction.support.TransactionSynchronizationManager&#93; - Removed value &#91;org.springframework.jdbc.datasource.ConnectionHolder@1984a9d&#93; for key &#91;org.apache.commons.dbcp.BasicDataSource@f6f1b6&#93; from thread &#91;main&#93;
    DEBUG &#91;org.springframework.transaction.support.TransactionSynchronizationManager&#93; - Removed value &#91;org.springframework.orm.hibernate.SessionHolder@149f041&#93; for key &#91;net.sf.hibernate.impl.SessionFactoryImpl@29d294&#93; from thread &#91;main&#93;
    DEBUG &#91;org.springframework.orm.hibernate.HibernateTransactionManager&#93; - Closing Hibernate session &#91;net.sf.hibernate.impl.SessionImpl@a010ba&#93; after transaction
    DEBUG &#91;org.springframework.orm.hibernate.SessionFactoryUtils&#93; - Closing Hibernate session

    thanks

    Jonny

  2. #2
    Join Date
    Aug 2004
    Location
    San Mateo, CA
    Posts
    1,265

    Default

    This occurs because the call to the second method is from the target to the target, not the proxy. Hence it's not advised by default. You can set "exposeProxy" to true on your ProxyFactoryBean and do
    Code:
    &#40;&#40;MyType&#41; AopContext.currentProxy&#40;&#41;&#41;.methodOne&#40;&#41;;
    rather than simply call methodOne on this.

    Rgds
    Rod
    Rod Johnson - GM, SpringSource Division, VMware
    http://www.springsource.com
    Spring From the Source

  3. #3
    Join Date
    Aug 2004
    Location
    San Francisco
    Posts
    423

    Default

    Thanks Rod, someone else also cleared this up for me in another thread.

    I'm wondering if this behaviour should be better documented? I realize, once it was pointed out to me, that this is expected behaviour based on the proxy implementation, but coming from the viewpoint of just using the AOP solution and not needing to know how they work, this isn't the expected behaviour.

    Also, I've some AspectJ experience, which probably biased me into what I should be expecting (that the second method should also be advised).

    thanks again,
    Jonny

    Quote Originally Posted by Rod Johnson
    This occurs because the call to the second method is from the target to the target, not the proxy. Hence it's not advised by default. You can set "exposeProxy" to true on your ProxyFactoryBean and do
    Code:
    &#40;&#40;MyType&#41; AopContext.currentProxy&#40;&#41;&#41;.methodOne&#40;&#41;;
    rather than simply call methodOne on this.

    Rgds
    Rod

Similar Threads

  1. Unit testing with JOTM and JtaTransactionManager
    By lalle in forum Architecture
    Replies: 1
    Last Post: Oct 15th, 2005, 09:05 AM
  2. Replies: 0
    Last Post: Jun 6th, 2005, 06:22 AM
  3. Replies: 3
    Last Post: May 16th, 2005, 07:04 AM
  4. Replies: 3
    Last Post: Nov 19th, 2004, 07:16 PM
  5. Transaction pb Hibernate/MySQL
    By syluser in forum Data
    Replies: 2
    Last Post: Aug 28th, 2004, 02:40 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •