JDBC Spring数据 @Transactional不起作用

huangapple go评论103阅读模式
英文:

JDBC Spring data @Transactional not working

问题

我正在使用Spring Boot和Spring Data JDBC。

我编写了这个Repository类

  1. @Repository
  2. @Transactional(rollbackFor = Exception.class)
  3. public class RecordRepository {
  4. public RecordRepository() {}
  5. public void insert(Record record) throws Exception {
  6. JDBCConfig jdbcConfig = new JDBCConfig();
  7. SimpleJdbcInsert messageInsert = new SimpleJdbcInsert(jdbcConfig.postgresDataSource());
  8. messageInsert.withTableName(record.tableName()).execute(record.content());
  9. throw new Exception();
  10. }
  11. }

然后我编写了一个客户端类来调用insert方法

  1. @EnableJdbcRepositories()
  2. @Configuration
  3. public class RecordClient {
  4. @Autowired
  5. private RecordRepository repository;
  6. public void insert(Record r) throws Exception {
  7. repository.insert(r);
  8. }
  9. }

我期望当调用RecordClientinsert()方法时,不会向数据库插入记录,因为RecordRepositoryinsert()方法抛出了Exception。然而实际上记录确实被添加了。

我漏掉了什么吗?

编辑。这是我配置数据源的类

  1. @Configuration
  2. @EnableTransactionManagement
  3. public class JDBCConfig {
  4. @Bean
  5. public DataSource postgresDataSource() {
  6. DriverManagerDataSource dataSource = new DriverManagerDataSource();
  7. dataSource.setDriverClassName("org.postgresql.Driver");
  8. dataSource.setUrl("jdbc:postgresql://localhost:5432/db");
  9. dataSource.setUsername("postgres");
  10. dataSource.setPassword("root");
  11. return dataSource;
  12. }
  13. }
英文:

I'm using springboot and spring-data-jdbc.

I wrote this repository class

  1. @Repository
  2. @Transactional(rollbackFor = Exception.class)
  3. public class RecordRepository {
  4. public RecordRepository() {}
  5. public void insert(Record record) throws Exception {
  6. JDBCConfig jdbcConfig = new JDBCConfig();
  7. SimpleJdbcInsert messageInsert = new SimpleJdbcInsert(jdbcConfig.postgresDataSource());
  8. messageInsert.withTableName(record.tableName()).execute(record.content());
  9. throw new Exception();
  10. }
  11. }

Then I wrote a client class that invokes the insert method

  1. @EnableJdbcRepositories()
  2. @Configuration
  3. public class RecordClient {
  4. @Autowired
  5. private RecordRepository repository;
  6. public void insert(Record r) throws Exception {
  7. repository.insert(r);
  8. }
  9. }

I would expect that no record are insert to db when RecordClient's insert() method is invoked, because RecordRespository's insert() throws Exception. Instead the record is added however.

What am I missing?

EDIT. This is the class where I configure my Datasource

  1. @Configuration
  2. @EnableTransactionManagement
  3. public class JDBCConfig {
  4. @Bean
  5. public DataSource postgresDataSource() {
  6. DriverManagerDataSource dataSource = new DriverManagerDataSource();
  7. dataSource.setDriverClassName("org.postgresql.Driver");
  8. dataSource.setUrl("jdbc:postgresql://localhost:5432/db");
  9. dataSource.setUsername("postgres");
  10. dataSource.setPassword("root");
  11. return dataSource;
  12. }
  13. }

答案1

得分: 2

你需要注入你的 datasource,而不是手动创建它。我猜这是因为 @Transactional 只对 Spring 管理的 bean 起作用。如果你通过调用 new 构造函数(例如 new JDBCConfig(). postgresDataSource())来创建数据源实例,那么你是在手动创建它,它不是一个由 Spring 管理的 bean。

  1. @Repository
  2. @Transactional(rollbackFor = Exception.class)
  3. public class RecordRepository {
  4. @Autowired
  5. DataSource dataSource;
  6. public RecordRepository() {}
  7. public void insert(Record record) throws Exception {
  8. SimpleJdbcInsert messageInsert = new SimpleJdbcInsert(dataSource);
  9. messageInsert.withTableName(record.tableName()).execute(record.contents());
  10. throw new Exception();
  11. }
  12. }
英文:

You have to inject your datasource instead of creating it manually. I guess because @Transactional only works for Spring managed beans. If you create a datasource instance by calling new constructor (like this new JDBCConfig(). postgresDataSource()), you are creating it manually and it's not a Spring managed beans.

  1. @Repository
  2. @Transactional(rollbackFor = Exception.class)
  3. public class RecordRepository {
  4. @Autowired
  5. DataSource dataSource;
  6. public RecordRepository() {}
  7. public void insert(Record record) throws Exception {
  8. SimpleJdbcInsert messageInsert = new SimpleJdbcInsert(dataSource);
  9. messageInsert.withTableName(record.tableName()).execute(record.contents());
  10. throw new Exception();
  11. }
  12. }

huangapple
  • 本文由 发表于 2020年10月2日 17:06:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/64168926.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定