Spring Data MongoDB 中的@Transactional(+测试容器)

问题描述 投票:0回答:1

我无法让事务在我的基本 spring data mongodb 应用程序中工作。我在这里读过文章和类似的问题,但似乎没有任何帮助。该测试正在使用 Testcontainers 运行,它似乎使用副本集启动 Mongo,这意味着事务应该正常工作。我确信测试配置至少可以在非事务性代码中正常工作(更多内容请参见最后的 github 链接)。

域名服务:

public class EntityDomainService {

  private final EntityARepository repository;
  private final EntityBRepository entityBRepository;

  EntityDomainService(EntityARepository repository, EntityBRepository entityBRepository) {
    this.repository = repository;
    this.entityBRepository = entityBRepository;
  }

  @Transactional
  public void transactionalAdd(String id1, String id2) {
    repository.save(EntityA.builder().id(id1).build());
    fail();
    repository.save(EntityA.builder().id(id2).build());
  }

  private void fail() {
    throw new RuntimeException();
  }
}

模块特定配置:

@Configuration
@EnableMongoRepositories
class EntityDomainConfiguration {
  @Bean
  EntityDomainService domainService(
      EntityARepository entityARepository, EntityBRepository entityBRepository) {
    return new EntityDomainService(entityARepository, entityBRepository);
  }
}

“全局”Mongo 配置:

@Configuration
@EnableMongoRepositories()
@EnableTransactionManagement
class ApplicationConfiguration extends AbstractMongoClientConfiguration {
  // usual stuff

  @Bean
  MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
    return new MongoTransactionManager(dbFactory);
  }
}

测试 Mongo 容器配置:

@EnableMongoRepositories
public class MongoDBContainerTestConfiguration {

  @Bean
  @ServiceConnection
  public MongoDBContainer mongoDBContainer() {
    return new MongoDBContainer(DockerImageName.parse("mongo:7.0")).withExposedPorts(27017);
  }
}

最后,测试本身:

@Testcontainers
@DataMongoTest
@ContextConfiguration(classes = [MongoDBContainerTestConfiguration.class])
class EntityADomainSpec extends Specification {

    @Autowired EntityAMongoRepository simulationRepository
    @Autowired EntityBMongoRepository plotRepository

    EntityDomainService service

    def setup() {
        service = new EntityDomainConfiguration().domainService(simulationRepository, plotRepository)
    }

    def cleanup() {
        simulationRepository.deleteAll()
        plotRepository.deleteAll()
    }

    def "basic transaction test"() {
        when:
        service.transactionalAdd("abc", "def")

        then:
        thrown(RuntimeException)
        !simulationRepository.existsById("abc")
    }
}

整个最小的可重现示例托管在我的 github 上(我希望它被修剪到最少,但这是我的第一次尝试)。它包含一项通过测试(以显示配置的有效性)和事务行为的实际测试: https://github.com/rafalszulejko/mongotransactions

编辑:从 github 托管的示例中删除了很多代码

mongodb spring-data-mongodb testcontainers spring-boot-testcontainers
1个回答
0
投票

答案是将非测试配置添加到

@ContextConfiguration

@ContextConfiguration(classes = [EntityDomainConfiguration.class, MongoDBContainerTestConfiguration.class])
© www.soinside.com 2019 - 2024. All rights reserved.