私は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メソッドが作成されていないことがわかります。
私はここで何が欠けていますか?