我希望确保 @Transactional 注解能够正常工作,因此我编写了一个测试来保存和发布文章。我的 Kafka 发布者是一个模拟器,会在任何调用时抛出异常。我希望确保 MongoDB 回滚已持久化的文章。
@Test
void testRollbackOnPublishFail() {
when(producer.publishArticle(any())).thenThrow(IllegalStateException.class);
ArticleDocument articleDocument = ArticleTestDataUtil.createArticleDocument();
try {
ArticleDocument publishedDocument = articleService.saveAndPublish(articleDocument);
} catch (Exception e) {
assertTrue(e instanceof IllegalStateException);
}
assertFalse(articleService.findById(articleDocument.getId()).isPresent());
}
我正在使用Flapdoodle的嵌入式MongoDB进行集成测试。
testCompile "de.flapdoodle.embed:de.flapdoodle.embed.mongo:2.2.0"
这个测试失败是因为默认情况下没有开启事务/复制。
因此,通过创建MongoTransactionManager来激活事务:
@Configuration
public class MongoTransactionConfig {
@Bean
public MongoTransactionManager transactionManager(MongoDbFactory dbFactory) {
return new MongoTransactionManager(dbFactory);
}
}
现在我的测试失败了,因为无法在MongoClient中启动会话。
com.mongodb.MongoClientException: Sessions are not supported by the MongoDB cluster to which this client is connected
at com.mongodb.MongoClient.startSession(MongoClient.java:560)
我也尝试创建自定义IMongodConfig
@Bean(name = "customReplicaMongodConfig")
public IMongodConfig mongodConfig(EmbeddedMongoProperties embeddedProperties) throws IOException {
Storage storage = new Storage("/tmp", "rs0", 0);
return new MongodConfigBuilder()
.shardServer(true)
.version(Version.V4_0_2)
.net(new Net(27117, Network.localhostIsIPv6()))
.replication(storage)
.cmdOptions(new MongoCmdOptionsBuilder().useNoJournal(false).build()).build();
}
并开始复制:
@ConditionalOnBean(name = "customReplicaMongodConfig")
@Configuration
public class ReplicaConfig {
@Inject
private MongoClient mongoClient;
@PostConstruct
public void initiateReplicationSet() {
mongoClient.getDatabase("admin").runCommand(new Document("replSetInitiate", new Document()));
}
}
但 replSetInitiate 超时失败。
所以我的问题是是否可能使用嵌入式 MongoDB 创建运行中的复制集来测试事务性。