2012-12-14 196 views
4

春季聲明式交易不起作用(未提交)。春季聲明式交易不起作用(交易未提交)

Spring配置文件

<!-- DATASOURCE --> 

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 
     <property name="driverClassName" value="${jdbc.driver}"/> 
     <property name="url" value="${jdbc.url}"/> 
     <property name="username" value="${jdbc.user}"/> 
     <property name="password" value="${jdbc.password}"/> 
     <property name="initialSize" value="${dbcp.initialSize}"/> 
     <property name="maxActive" value="${dbcp.maxActive}"/> 
     <property name="maxIdle" value="${dbcp.maxIdle}"/> 
     <property name="maxWait" value="${dbcp.maxWait}"/> 
     <property name="poolPreparedStatements" value="${dbcp.poolPreparedStatements}"/> 
     <property name="validationQuery" value="select 1 from dual"/> 
     <property name="testOnBorrow" value="${dbcp.testOnBorrow}"/> 
     <property name="maxOpenPreparedStatements" value="${dbcp.maxOpenPreparedStatements}"/> 
     <property name="logAbandoned" value="${dbcp.logAbandoned}"/> 
     <property name="removeAbandoned" value="${dbcp.removeAbandoned}"/> 
     <property name="removeAbandonedTimeout" value="${dbcp.removeAbandonedTimeout}"/> 
     **<property name="defaultAutoCommit" value="false"/>** 
    </bean> 

    <!-- IBATIS --> 

    <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> 
     <property name="configLocations" value="classpath:/config/ibatis/sqlMapConfig.xml"/> 
     <property name="dataSource" ref="dataSource"/> 
    </bean> 

    <bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate"> 
     <property name="sqlMapClient" ref="sqlMapClient"/> 
    </bean> 

    <!-- TRANSACTION --> 

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
     <property name="dataSource" ref="dataSource"/> 
    </bean> 

    <tx:advice id="txAdvice" transaction-manager="transactionManager"> 
     <tx:attributes> 
      <tx:method name="*" propagation="REQUIRED" isolation="READ_COMMITTED" timeout="10" read-only="false"/> 
     </tx:attributes> 
    </tx:advice> 

    <aop:config> 
     <aop:pointcut id="serviceMethods" expression="execution(public * com.store.web.front.service.*.*(..))"/> 
     <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods"/> 
    </aop:config> 

控制器豆

package com.store.web.front.controller; 

    public interface TestTxControllerIF { 
     public ModelAndView transaction(); 
    } 

package com.store.web.front.controller; 

    @Controller 
    public class TestTxControllerImpl implements TestTxControllerIF { 

     @Autowired 
     protected TestTxServiceIF testService; 

     Logger     logger = Logger.getLogger(TestTxControllerIF.class); 

     @Override 
     @RequestMapping(value = "/test/tx.html") 
     public ModelAndView transaction() { 

      logger.info("# TestTxController.transaction() - " + testService); 

      testService.transaction(); 
      return new ModelAndView("main"); 
     } 
} 

服務豆

package com.store.web.front.service; 

     public interface TestTxServiceIF { 
      public void transaction(); 
     } 

    package com.store.web.front.service; 

     @Service 
     public class TestTxServiceImpl implements TestTxServiceIF { 

      Logger logger = Logger.getLogger(TestTxServiceImpl.class); 

      @Autowired 
      protected TestDaoIF testDao; 

      @Override 
      public void transaction() { 

       logger.info("# TestTxService.transaction()"); 

       Test test1 = new Test("111", "First"); 
       Test test2 = new Test("222", "Second"); 
       Test test3 = new Test("333", "Third"); 

       testDao.insertTest(test1);   
       logger.info("# Successfully inserted!!! - " + test1); 

       testDao.insertTest(test2);   
       testDao.insertTest(test3); 
      } 
     } 

DAO豆

package com.store.web.front.dao; 

    public interface TestDaoIF { 
     public void insertTest(Test test); 
    } 

package com.store.web.front.dao; 

    @Repository 
    public class TestDaoImpl extends AbstractIBatisDao implements TestDaoIF {  

     Logger logger = Logger.getLogger(TestTxServiceImpl.class); 

     @Override 
     public void insertTest(Test test) { 

      logger.info("# TestDao.insertTest()"); 

      template.insert("test.insertTest", test); 
     } 
    } 

結果&問題

部署併發送請求「/test/tx.html」後,事務執行沒有問題,但數據庫記錄不會持久。 我想,交易沒有提交。 問題是什麼?

日誌

DEBUG> 11:02:10 - DispatcherServlet with name 'spring-dispatcher' processing request for [/test/tx.html] ☜ DispatcherServlet.java:781 
DEBUG> 11:02:10 - Invoking request handler method: public org.springframework.web.servlet.ModelAndView com.store.web.front.controller.TestTxControllerImpl.transaction() ☜ HandlerMethodInvoker.java:134 
INFO > 11:02:10 - # TestTxController.transaction() - [email protected] ☜ TestTxControllerImpl.java:23 
INFO > 11:02:10 - # TestTxService.transaction() ☜ TestTxServiceImpl.java:25 
INFO > 11:02:10 - # TestDao.insertTest() ☜ TestDaoImpl.java:20 
DEBUG> 11:02:10 - Opened SqlMapSession [[email protected]] for iBATIS operation ☜ SqlMapClientTemplate.java:177 
DEBUG> 11:02:10 - Fetching JDBC Connection from DataSource ☜ DataSourceUtils.java:112 
DEBUG> 11:02:10 - Obtained JDBC Connection [jdbc:oracle:thin:@localhost:1521:XE, UserName=STORE, Oracle JDBC driver] for iBATIS operation ☜ SqlMapClientTemplate.java:194 
DEBUG> 11:02:10 - Returning JDBC Connection to DataSource ☜ DataSourceUtils.java:312 
INFO > 11:02:10 - # Successfully inserted!!! - Test [id=111, name=First] ☜ TestTxServiceImpl.java:33 
+1

什麼是TestTxServiceImpl類的完全限定名稱? –

+0

使用STS,並檢查建議的標記是否顯示在服務方法旁邊。如果沒有出現,那麼也許你的建議配置不正確。 – Ralph

+0

全限定類名是「com.store.web.front.service.TestTxServiceImpl」。 – user1903286

回答

0

,我發現這個問題的原因。 事務聲明文件由DispatcherServlet加載時, 事務控制成功。 但是文件被ContextLoaderListener加載,事務控制不好。 我不知道爲什麼會出現這種差異。 你能向我解釋一下嗎?

0

豆用「AOP東西」裝飾BeanPostProcessor s(在你的情況下可能是AspectJAwareAdvisorAutoProxyCreator)。這些後處理器豆是上下文實例特定

如果您在servlet上下文配置AOP,你必須在根上下文(反之亦然)目標豆,那麼這就是爲什麼不施加切入點。

通常的做法是具有較低級別的豆類(服務和DAO)與在根上下文 AOP配置在一起,並在servlet上下文只留下UI豆(MVC的東西)。