2017-05-02 9 views
1

私のメソッドでいくつかの挿入をしたいし、何かがうまくいかない場合、すべての挿入をロールバックしたいと思います。 は、ここに私のJDBC Bean定義Spring JDBCでトランザクションをロールバックする方法は?

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xmlns="http://www.springframework.org/schema/beans" xmlns:tx="http://www.springframework.org/schema/tx" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/context 
     http://www.springframework.org/schema/context/spring-context.xsd 
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> 

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

    <context:property-placeholder location="classpath:jdbc.properties"/> 

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
     <property name="driverClassName" value="${jdbc.driverClassName}"/> 
     <property name="url" value="${jdbc.url}"/> 
     <property name="username" value="${jdbc.username}"/> 
     <property name="password" value="${jdbc.password}"/> 
    </bean> 

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> 
     <property name="dataSource" ref="dataSource"/> 
    </bean> 

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

</beans> 

だし、ここで、それは実行時例外0/0

を満たした後、私は、それが最初のインサートをロールバックしたい私の方法

@Transactional 
public void save(Map<String, String> properties, Long moduleId, 
       String language, String propertyFileName, String filePath) { 

    KeyHolder keyHolder = new GeneratedKeyHolder(); 

    final String propertyFileQuery = "INSERT INTO property_file " + 
      "(moduleId, languageId, propertyFileName,hash,path) " + 
      "VALUES (?,?,?,?,?)"; 

    jdbcTemplate.update(connection -> { 
     PreparedStatement ps = 
       connection.prepareStatement(propertyFileQuery, new String[]{"id"}); 
     ps.setLong(1, moduleId); 
     ps.setString(2, language); 
     ps.setString(3, propertyFileName); 
     ps.setString(4, "hash goes here"); 
     ps.setString(5, filePath); 

     return ps; 
    }, keyHolder); 

    int x = 0/0; 

    final String propertiesQuery = "INSERT INTO property_value " + 
      "(propertyFileId, propKey, propValue) " + 
      "VALUES (?,?,?)"; 

    properties.forEach((key, value) -> jdbcTemplate.update(
      propertiesQuery, keyHolder.getKey(), key, value 
    )); 

} 

だが、データがに入りますデータベースに格納され、ロールバックされません。

私は間違っていますか?

答えて

0

を使用することができます。トランザクション管理は大丈夫でした。トランザクションで仕事をすることができなかった理由は、MySQLエンジンのためでした。それはMyISAMに設定されました。 MySQLウェブサイトに引用されているように

MyISAMはトランザクションをサポートしていない可能性があります。

テーブルをMyISAMからInnoDbに変更して機能させました。

0

@Transactionalをクラスにバインドするのではなく、クラスにバインドするのではなく、クラスにバインドすると、すべてのアクションが1つのグローバルトランザクションに参加し、トランザクションが失敗した場合にアクションがロールバックされる

0
private PlatformTransactionManager transactionManager; 

public void setDataSource(DataSource dataSource) { 

    this.jdbcTemplate = new JdbcTemplate(dataSource); 
} 

public void setTransactionManager(PlatformTransactionManager transactionmanager) { 
    this.transactionManager = transactionmanager; 
} 

、あなたが

TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition()); 

を使用する必要がありますし、jdbcTemplate.update後、あなたが取引

をコミットする必要がメソッド内
 transactionManager.commit(status); 

あなたはまた、理由を見つけた@Transactional(propagation=Propagation.REQUIRED) `

+0

doens't work:/ – Carmine

関連する問題