Spring @ Transaction not rollback

I am using Spring NamedParameterJdbcTemplate, and I am trying to use @Transactionalto make sure that two inserts are either stored in the database, or one of them is rolled back if the other does not work.

The code is designed to work with MySql and is tested with H2 in memory.

It does not work ... The second insert fails, but the first does not roll back.

Here are the relevant classes:

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);
    }
}

The test I'm running is: Send a list of items to storeElements(), but make sure one of the items has extraDataone that is too long to store in TableB. Then I check the database to make sure no items have been stored in the database.

Paste is not performed, but rollback is not performed.

Spring , storeElements.

debug, , DataSourceTransactionManager , , Spring.

?

+4
1

MySpringConfig @EnableTransactionManagement, .

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

Source: https://habr.com/ru/post/1662410/


All Articles