JDBC Spring数据 @Transactional不起作用

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

JDBC Spring data @Transactional not working

问题

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

我编写了这个Repository类

@Repository
@Transactional(rollbackFor = Exception.class)
public class RecordRepository {
    public RecordRepository() {}

    public void insert(Record record) throws Exception {
        JDBCConfig jdbcConfig = new JDBCConfig();
        SimpleJdbcInsert messageInsert = new SimpleJdbcInsert(jdbcConfig.postgresDataSource());

        messageInsert.withTableName(record.tableName()).execute(record.content());
        throw new Exception();
    }
}

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

@EnableJdbcRepositories()
@Configuration
public class RecordClient {
    @Autowired
    private RecordRepository repository;

    public void insert(Record r) throws Exception {
        repository.insert(r);
    }
}

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

我漏掉了什么吗?

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

@Configuration
@EnableTransactionManagement
public class JDBCConfig {

    @Bean
    public DataSource postgresDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("org.postgresql.Driver");
        dataSource.setUrl("jdbc:postgresql://localhost:5432/db");
        dataSource.setUsername("postgres");
        dataSource.setPassword("root");

        return dataSource;
    }
}
英文:

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

I wrote this repository class

@Repository
@Transactional(rollbackFor = Exception.class)
public class RecordRepository {
    public RecordRepository() {}

    public void insert(Record record) throws Exception {
        JDBCConfig jdbcConfig = new JDBCConfig();
        SimpleJdbcInsert messageInsert = new SimpleJdbcInsert(jdbcConfig.postgresDataSource());

        messageInsert.withTableName(record.tableName()).execute(record.content());
        throw new Exception();
    }
}

Then I wrote a client class that invokes the insert method

@EnableJdbcRepositories()
@Configuration
public class RecordClient {
    @Autowired
    private RecordRepository repository;

    public void insert(Record r) throws Exception {
        repository.insert(r);
    }
}

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

@Configuration
@EnableTransactionManagement
public class JDBCConfig {

    @Bean
    public DataSource postgresDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("org.postgresql.Driver");
        dataSource.setUrl("jdbc:postgresql://localhost:5432/db");
        dataSource.setUsername("postgres");
        dataSource.setPassword("root");

        return dataSource;
    }
}

答案1

得分: 2

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

@Repository
@Transactional(rollbackFor = Exception.class)
public class RecordRepository {

  @Autowired
  DataSource dataSource;

  public RecordRepository() {}

  public void insert(Record record) throws Exception {
    SimpleJdbcInsert messageInsert = new SimpleJdbcInsert(dataSource);
    messageInsert.withTableName(record.tableName()).execute(record.contents());
    throw new Exception();
  }
}
英文:

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.

@Repository
@Transactional(rollbackFor = Exception.class)
public class RecordRepository {

  @Autowired
  DataSource dataSource;

  public RecordRepository() {}

  public void insert(Record record) throws Exception {
    SimpleJdbcInsert messageInsert = new SimpleJdbcInsert(dataSource);
    messageInsert.withTableName(record.tableName()).execute(record.contents());
    throw new Exception();
  }
}

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:

确定