Spring @Transactional 不回滚

Spring @Transactional not rolling back

我正在使用 Spring 的 NamedParameterJdbcTemplate 并且我正在尝试使用 @Transactional 来确保两个插入都保存到数据库中或者一个被滚动回来,以防另一个失败。

代码设计为 运行 MySql 并且正在内存中使用 H2 进行测试。

它不工作...第二次插入失败但第一次没有回滚。

这里是相关的类:

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(),但要确保其中一个元素的 extraData 太长而无法发送存储在 TableB 中。然后我检查数据库以确保没有元素存储在数据库中。

插入失败,但没有回滚。

整个代码是一个Spring栈,从测试一直到storeElements方法。

运行 调试,我看到 none 的 DataSourceTransactionManager 方法在加载 Spring 上下文时被调用,除了构造函数之外。

我在这里错过了什么?

@EnableTransactionManagement 注释您的 MySpringConfig 以启用事务管理。

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