Spring Boot测试不回滚事务(MS SQL Server,Spring Boot 2.7.5)

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

Spring Boot Test not rolling back transactions (MS SQL Server, Spring Boot 2.7.5)

问题

以下是您要翻译的内容:

"我正在为一个具有多个数据源的项目编写集成测试,并希望测试存储库和服务层。问题是 @Transactional 注解不起作用,测试期间插入的数据被持久化。

这是一个简单的集成测试。我需要使用 @SpringBootTest 而不是 @DataJpaTest,因为多个数据源在一个处理将正确的数据源分配给正确的存储库的 bean 中进行了配置。

@SpringBootTest(classes = { MyApp.class, TestSecurityConfiguration.class })
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ActiveProfiles("database-test")
@Transactional
@Rollback
public class MyIT {

  1. @Autowired
  2. ChannelRepository channelRepository;
  3. @Test
  4. public void testChannels() {
  5. Channel testChannel1 = new Channel();
  6. testChannel1.setDescription("Test Channel 1");
  7. channelRepository.save(testChannel1);
  8. Channel testChannel2 = new Channel();
  9. testChannel2.setDescription("Test Channel 2");
  10. channelRepository.save(testChannel2);
  11. Channel channel = channelRepository.findById(1).get();
  12. assertThat(channel).isNotNull();
  13. }

}

在 application.yml 中配置的方言是 "org.hibernate.dialect.SQLServer2012Dialect",数据库是运行在专用服务器上的测试数据库,而不是内嵌数据库。

数据被插入而没有回滚。"

英文:

I am writing integration tests for a project with multiple datasources and want to test the repository and service layer. Problem is that the @Transactional annotation is not working and data inserted during tests is persisted.

This is a simple IT. I need to use @SpringBootTest instead of @DataJpaTest because multiple datasources are configured in a bean which handles assigning the right datasource to the correct repository.

  1. @SpringBootTest(classes = { MyApp.class, TestSecurityConfiguration.class })
  2. @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
  3. @ActiveProfiles("database-test")
  4. @Transactional
  5. @Rollback
  6. public class MyIT {
  7. @Autowired
  8. ChannelRepository channelRepository;
  9. @Test
  10. public void testChannels() {
  11. Channel testChannel1 = new Channel();
  12. testChannel1.setDescription("Test Channel 1");
  13. channelRepository.save(testChannel1);
  14. Channel testChannel2 = new Channel();
  15. testChannel2.setDescription("Test Channel 2");
  16. channelRepository.save(testChannel2);
  17. Channel channel = channelRepository.findById(1).get();
  18. assertThat(channel).isNotNull();
  19. }
  20. }

The dialect configured in the application.yml is "org.hibernate.dialect.SQLServer2012Dialect" and the database is our test database that runs on a dedicated server, not an embedded database.

The data is inserted without rollback.

答案1

得分: 0

在查看了JpaTransactionManager的日志后,我发现每次调用.save()时都会创建一个新的内部事务。我尝试通过将值传递给@Transactional注解来手动指定事务管理器,现在它可以正常工作了。看起来DataSource beans的配置可能不完全正确。我从这篇文章中得到了灵感,该文章使用ChainedTransactionManager来管理多个数据源https://medium.com/preplaced/distributed-transaction-management-for-multiple-databases-with-springboot-jpa-and-hibernate-cde4e1b298e4

英文:

After looking at the JpaTransactionManager logs using:

  1. logging:
  2. level:
  3. sql: DEBUG
  4. ROOT: DEBUG
  5. org.springframework.orm.jpa: DEBUG
  6. org.springframework.transaction: DEBUG

I saw that for each .save() call there was a new inner transaction. I tried to specify the transaction manager manually by passing the value to the @Transactional annotation and now it works. Looks like the DataSource beans are not picked up entirely correct. I got the idea based on this article where a ChainedTransactionManager is used for multiple datasources https://medium.com/preplaced/distributed-transaction-management-for-multiple-databases-with-springboot-jpa-and-hibernate-cde4e1b298e4

huangapple
  • 本文由 发表于 2023年1月9日 18:37:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75056041.html
匿名

发表评论

匿名网友

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

确定