2016-11-30 21 views
4

私はSpringのNamedParameterJdbcTemplateを使用していますが、他の1つが失敗した場合に2つの挿入がデータベースに保持されているか、ロールバックされていることを確認するために@Transactionalを使用しようとしています。Spring @トランザクションがロールバックしない

このコードはMySqlで実行するように設計されており、メモリ内のH2でテストされています。

これは機能しません... 2番目の挿入は失敗しますが、最初の挿入はロールバックされません。ここで

は、関連するクラスです:

MySpringConfig.java

package com.MyPackage.spring 

@Configuration 
@ComponentScan({ "com.MyPackage" }) 
public class MySpringConfig { 

@Bean 
public NamedParameterJdbcTemplate namedParameterJdbcTemplate() throws Exception { 
    return new NamedParameterJdbcTemplate(dataSource()); 
} 

@Bean 
public DataSourceTransactionManager dataSourceTransactionManager() throws Exception { 
    return new DataSourceTransactionManager(dataSource()); 
} 


@Bean(name = "customerEntitiesDataSource") 
public DataSource dataSource() throws Exception { 
    Properties properties = new Properties(); 
    properties.put("url", "db-url"); 
    properties.put("username", "uName"); 
    properties.put("password", "pwd"); 
    BasicDataSource dataSource = BasicDataSourceFactory.createDataSource(properties); 
    return dataSource; 
} 
} 

MyDao.java

package com.MyPackage.dao 

@Repository 
public class MyDao { 
    private ObjectMapper mapper = new ObjectMapper(); 

    @Autowired 
    private NamedParameterJdbcTemplate jdbcTemplate; 

    private static String INSERT_ELEMENT_QUERY = "INSERT INTO TableA..." + " VALUES (:param1, :param2)"; 

    @Transactional(rollbackFor = {Exception.class}, propagation=Propagation.REQUIRED) 
    public void storeElements(List<Element> element) { 


     Stream<HashMap<String, Object>> hashMapStream = elements.stream().map(
       element -> { 
        HashMap<String, Object> params = new HashMap<>(); 
        params.put("param1", element.getParam1()); 
        params.put("param2", element.getParam2()); 
        return params; 
       } 
     ); 
     List<Map<String, Object>> collect = hashMapStream.collect(Collectors.<Map<String, Object>>toList()); 
     Map<String, Object>[] batchValues = new Map[]{}; 
     batchValues = collect.toArray(batchValues); 

     jdbcTemplate.batchUpdate(INSERT_ELEMENT_QUERY, batchValues); 

     computers.stream().forEach(element -> saveExtraData(element)); 
    } 


    private static String INSERT_ELEMENT_EXTRA_DATA_QUERY = "INSERT INTO TableB... Values (:val1, :val2)"; 

    @Transactional(rollbackFor = {Exception.class}, propagation=Propagation.REQUIRED) 
    public void saveExtraData(Element element) { 

     Stream<HashMap<String, Object>> hashMapStream = element.getExtraData().stream().map(
       extra -> { 
        HashMap<String, Object> params = new HashMap<>(); 
        params.put("val1", extra.getVal1()); 
        params.put("val2", extra.getVal2()); 
        return params; 
       } 
     ); 
     List<Map<String, Object>> collect = hashMapStream.collect(Collectors.<Map<String, Object>>toList()); 
     Map<String, Object>[] batchValues = new Map[]{}; 
     batchValues = collect.toArray(batchValues); 

     jdbcTemplate.batchUpdate(INSERT_ELEMENT_EXTRA_DATA_QUERY , batchValues); 
    } 
} 

私が実行しているテストがある:のリストを送信要素はstoreElements()になりますが、要素の1つにextraDataは長すぎてTableBに格納できません。次に、データベースをチェックして、要素がデータベースに格納されていないことを確認します。

挿入に失敗しましたが、ロールバックはありません。

コード全体は、テストからすべての方法でstoreElementsメソッドまでSpringスタックです。

デバッグを実行すると、コンストラクタを除いて、SpringコンテキストがロードされたときにDataSourceTransactionManagerメソッドが作成されていないことがわかります。

私はここで何が欠けていますか?

答えて

2

お客様のMySpringConfig@EnableTransactionManagementと注釈を付けると、トランザクション管理が有効になります。

@Configuration 
@ComponentScan({ "com.MyPackage" }) 
@EnableTransactionManagement 
public class MySpringConfig { 
関連する問題