2013-05-17 59 views
4

我是Spring交易的新手。我使用Spring 3.2.2和MySQL 5.5.20(InnoDB)。我可以在日誌文件中看到它確實回滾了,但在數據庫中,記錄仍然更新爲9.我錯過了什麼?謝謝。JDBC的非常簡單的Spring事務不會回滾(即使日誌說是)

config.xml文件:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 
     <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 
     <property name="url" value="jdbc:mysql://127.0.0.1:3306/javatest?useUnicode=true&amp;characterEncoding=UTF-8" /> 
     <property name="username" value="root" /> 
     <property name="password" value="xxx" /> 
</bean> 

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

<bean id="hello" class="com.xol.oss.HelloService"> 
    <property name="dataSource" ref="dataSource"/> 
</bean> 

<tx:annotation-driven transaction-manager="txManager"/> 

的Java代碼:

public void setDataSource(BasicDataSource dataSource) { 
    this.dataSource = dataSource; 
} 

@Transactional 
public void getData() { 
    Connection con=null; 
    try { 
     con = dataSource.getConnection(); 
     Statement stat = con.createStatement(); 
     stat.executeUpdate("update testdata set foo=9 where id=1"); 
     throw new RuntimeException("an Exception for test"); 
    } catch (SQLException e) { 
     e.printStackTrace(); 
    } finally{ 
     try { 
      con.close(); 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

日誌說,它並回滾:

15:15:36,936 DEBUG DataSourceTransactionManager:366 - Creating new transaction with name [com.xol.oss.HelloService.getData]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' 
15:15:37,525 DEBUG DataSourceTransactionManager:205 - Acquired Connection [jdbc:mysql://127.0.0.1:3306/javatest?useUnicode=true&characterEncoding=UTF-8, [email protected], MySQL-AB JDBC Driver] for JDBC transaction 
15:15:37,535 DEBUG DataSourceTransactionManager:222 - Switching JDBC Connection [jdbc:mysql://127.0.0.1:3306/javatest?useUnicode=true&characterEncoding=UTF-8, [email protected], MySQL-AB JDBC Driver] to manual commit 
15:15:37,581 DEBUG DataSourceTransactionManager:844 - Initiating transaction rollback 
15:15:37,582 DEBUG DataSourceTransactionManager:280 - Rolling back JDBC transaction on Connection [jdbc:mysql://127.0.0.1:3306/javatest?useUnicode=true&characterEncoding=UTF-8, [email protected], MySQL-AB JDBC Driver] 
15:15:37,583 DEBUG DataSourceTransactionManager:323 - Releasing JDBC Connection [jdbc:mysql://127.0.0.1:3306/javatest?useUnicode=true&characterEncoding=UTF-8, [email protected], MySQL-AB JDBC Driver] after transaction 
15:15:37,583 DEBUG DataSourceUtils:327 - Returning JDBC Connection to DataSource 
Exception in thread "main" java.lang.RuntimeException: an RuntimeException for test 
    at com.xol.oss.HelloService.getData(HelloService.java:31) 
    at com.xol.oss.HelloService$$FastClassByCGLIB$$3d7d84e8.invoke(<generated>) 

回答

5

的問題是,你不使用由spring管理的連接,而不是你打開一個新的連接。將代碼更改爲以下內容並嘗試。

import org.springframework.jdbc.datasource.DataSourceUtils;  

@Transactional 
public void getData() { 
    Connection con=null; 
    try { 
     // Get the connection associated with the transaction 
     con = DataSourceUtils.getConnection(dataSource); 
     Statement stat = con.createStatement(); 
     stat.executeUpdate("update testdata set foo=9 where id=1"); 
     throw new RuntimeException("an Exception for test"); 
    } catch (SQLException e) { 
     e.printStackTrace(); 
    } finally{ 
     DataSourceUtils.releaseConnection(dataSource, con); 
    } 
    } 

如果您正在編寫新代碼,則應該使用JdbcTemplate而不是原始jdbc。

class HelloService { 
    JdbcTemplate jdbcTemplate; 
    public setDataSource(DataSource dataSource) { 
     jdbcTemplate = new JDBCTemplate(dataSource); 
    } 

    @Transactional 
    public void getData() { 
     jdbcTemplate.update(update testdata set foo=9 where id=1); 
     throw new RuntimeException("an Exception for test"); 
    } 
+0

非常感謝,這就是我需要的。 – user2392773

+0

+1和羞辱我不是因爲:) –

+0

非常感謝。我花了2個小時不是這個。 – SalutonMondo