Announcement Announcement Module
Collapse
No announcement yet.
Problem with transaction autoproxy - help please! Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem with transaction autoproxy - help please!

    Hi,

    I'm trying to configure a service using autoproxy, and I'm having problem getting the transaction to work. In the following configuration, my application is not enlisting in a transaction, so the transaction won't rollback properly. I checked the book as well as online help, but I still could not figure out where are the missing pieces.

    please help!

    thanks


    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http&#58;//www.springframework.org/dtd/spring-beans.dtd">
    
    <beans>
    
    	<bean id="activeDataSource" class="org.apache.commons.dbcp.BasicDataSource" 
    		destroy-method="close">
    		<property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>
    		<property name="url"><value>jdbc&#58;oracle&#58;thin&#58;@hostname&#58;1521&#58;orange</value></property>
    		<property name="username"><value>user</value></property>
    		<property name="password"><value>pw</value></property>
    	</bean> 
    
    	<bean id="activeTransactionManager" 
    	   class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    	   <property name="dataSource">
    	   	<ref bean="activeDataSource"/>
    	   </property>
    	</bean>
    
    	<bean id="autoproxy" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
    
    	<bean id="transactionAdvisor"
    		class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
    		<constructor-arg>
    			<ref bean="transactionInterceptor"/>
    		</constructor-arg>
    	</bean>
    
    	<bean id="transactionInterceptor" 
    		class="org.springframework.transaction.interceptor.TransactionInterceptor">
    		<property name="transactionManager">
    			<ref bean="activeTransactionManager"/>
    		</property>
    		<property name="transactionAttributeSource">
    			<ref bean="transactionAttributeSource"/>
    		</property>
    	</bean>
    	
    		
    	<bean id="transactionAttributeSource" 
    		class="org.springframework.transaction.interceptor.MethodMapTransactionAttributeSource">
    		<property name="methodMap">
    			<map>
    				<entry key="com.beans.BoxHandling.BoxHandlingServiceImpl.save*">
    					<value>PROPAGATION_REQUIRED</value>
    				</entry>
    				<entry key="com.beans.BoxHandling.BoxHandlingServiceImpl.get*">
    					<value>PROPAGATION_SUPPORTS</value>
    				</entry>
    			</map>
    		</property>
    	</bean>
    	
    	<bean id="boxHandlingService"
    		class="com.beans.BoxHandling.BoxHandlingServiceImpl">
    		<property name="dataSource">
    			<ref bean="activeDataSource"/>
    		</property>
    	</bean>
    
    </beans>

  • #2
    Can you post the code for your service object that should be joining the transactions?

    Rob

    Comment


    • #3
      Hi Rob,

      Here is my serviceImple code sample that I used in my testing.

      thanks,
      Quoc

      Code:
      public class BoxHandlingServiceImpl implements BoxHandlingService
      &#123;
      	private DataSource	dataSource;
      
      	public void setDataSource&#40;DataSource ds&#41;
      	&#123;
      		this.dataSource = ds;
      	&#125;
      
      	public long saveBox&#40;DBox obj&#41; throws Exception
      	&#123;
      		Connection connect = DataSourceUtils.getConnection&#40;dataSource&#41;;
      		obj.setKey&#40;Calendar.getInstance&#40;&#41;.getTimeInMillis&#40;&#41;&#41;;
      		String sqlStmt = "INSERT  INTO BOX &#40; obj_name, obj_key &#41;  VALUES  &#40; N'" + obj.getName&#40;&#41;
      				+ "', " + obj.getKey&#40;&#41; + "&#41;";
      		PreparedStatement stmt = connect.prepareStatement&#40;sqlStmt&#41;;
      		stmt.execute&#40;&#41;;
      		if &#40;true&#41;
      		&#123;
      			throw new RuntimeException&#40;"Forcing exception to test transaction rollback!"&#41;;
      		&#125;
      		return obj.getKey&#40;&#41;;
      	&#125;
      &#125;

      Comment


      • #4
        The problem here is that you are not using Spring's data access support classes. By default, standard JDBC code is not aware of Spring-managed transactions. You have two options here. My preference would be to use JdbcTemplate to create your JDBC code and have Spring-managed transactions. If this is not possible, then you should configure a TransactionAwareDataSourceProxy for you DataSource and this will enable your JDBC code to participate in a Spring-managed transaction.

        Rob

        Comment


        • #5
          Hi Rob,

          Because I'm porting exist codes from an EJB app to Spring, I don't have the luxury to use JdbcTemplate. I've tried modifying my original datasource & transaction manger configuration as follow, but I still could not get it to work. I even stepped into the codes & confirmed that the dataSource is an instanceof TransactionAwareDataSourceProxy

          Code:
          	<bean id="activeDataSourceImpl" class="org.apache.commons.dbcp.BasicDataSource" 
          		destroy-method="close">
          		<property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>
          		<property name="url"><value>jdbc&#58;oracle&#58;thin&#58;@hostname&#58;1521&#58;orange</value></property>
          		<property name="username"><value>user</value></property>
          		<property name="password"><value>pw</value></property>
          	</bean> 
          	
          	<bean id="activeDataSource"
          		class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
          		<property name="targetDataSource">
          			<ref bean="activeDataSourceImpl"/>
          		</property>
          	</bean>
          
          	<bean id="transactionManager" 
          	   class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
          	   <property name="dataSource">
          	   	<ref bean="activeDataSourceImpl"/>
          	   </property>
          	</bean>
          Interestingly, the datasource transaction manager works fine for the following configuration.
          Code:
          <?xml version="1.0" encoding="UTF-8"?> 
          <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http&#58;//www.springframework.org/dtd/spring-beans.dtd"> 
          
          <beans> 
          
             <bean id="activeDataSource" class="org.apache.commons.dbcp.BasicDataSource" 
                destroy-method="close"> 
                <property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property> 
                <property name="url"><value>jdbc&#58;oracle&#58;thin&#58;@hostname&#58;1521&#58;orange</value></property> 
                <property name="username"><value>user</value></property> 
                <property name="password"><value>pw</value></property> 
             </bean> 
          
             <bean id="activeTransactionManager" 
                class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
                <property name="dataSource"> 
                   <ref bean="activeDataSource"/> 
                </property> 
             </bean> 
          
          	<bean id="boxHandlingServiceTarget"
          		class="com.beans.BoxHandling.BoxHandlingServiceImpl"
          		lazy-init="true">
          		<property name="activeDataSource">
          			<ref bean="activeDataSource"/>
          		</property>
          	</bean>
          	<bean id="boxHandlingService"
          		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
          		lazy-init="true">
          		<property name="transactionManager">
          			<ref bean="transactionManager"/>
          		</property>
          		<property name="target">
          			<ref local="boxHandlingServiceTarget"/>
          		</property>
          		<property name="transactionAttributes">
          			<props>
          				<prop key="*">PROPAGATION_REQUIRED</prop>
          			</props>
          		</property>
          	</bean>
          
          </beans>

          Comment

          Working...
          X