英文:
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);
}
}
我期望当调用RecordClient
的insert()
方法时,不会向数据库插入记录,因为RecordRepository
的insert()
方法抛出了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();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论