Quarkus 3.7.3中@TestReactiveTransaction未回滚问题求助
问题
在Quarkus 3.7.3中编写单元测试验证PanacheBaseRepository方法时,测试执行后数据库中插入的数据未被回滚。
Repository实现代码
@ApplicationScoped @WithTransaction public class FieldRepository implements PanacheRepositoryBase<FieldEntity, UUID> { public Uni<FieldEntity> updatePreview(UUID id, JsonObject value) { return update("previewValue = ?1, updated = true where id= ?2", value, id) .replaceWith(findById(id)); } }
测试代码(写法一)
@QuarkusTest @TestReactiveTransaction class AttributeRepositoryTest2 { @Test void shouldUpdateEntity(UniAsserter asserter) { FieldEntity entity = new FieldEntity(); var updatedValue = "updatedValue"; asserter.execute(() -> fieldRepository.persist(entity)) .assertThat(() -> fieldRepository.updatePreview(entity.id, updatedValue), fieldEntity -> Assertions.assertThat(fieldEntity) .extracting(field -> field.previewValue, field -> field.updated) .contains(updatedValue, true)) .surroundWith(u -> Panache.withTransaction(() -> u)); } }
测试代码(写法二)
@QuarkusTest @TestReactiveTransaction class AttributeRepositoryTest2 { @Test void shouldUpdateEntity(UniAsserter asserter) { FieldEntity entity = new FieldEntity(); var updatedValue = "updatedValue"; asserter.assertThat(() -> fieldRepository.persist(entity).chain(field -> fieldRepository.updatePreview(field.id, updatedValue)), fieldEntity -> Assertions.assertThat(fieldEntity) .extracting(field -> field.previewValue, field -> field.updated) .contains(updatedValue, true)) .surroundWith(u -> Panache.withTransaction(() -> u)); } }
两种写法均出现同一问题:事务未回滚,数据库中新增了记录。
解决方案
问题根源在于事务管理的重复嵌套与冲突:
测试类事务注解与手动事务调用冲突
测试类上的@TestReactiveTransaction注解会自动为整个测试方法创建并管理响应式事务,测试结束后自动回滚。但你额外调用了surroundWith(u -> Panache.withTransaction(() -> u)),相当于在已有事务外层再套一层新事务,打乱了原有的测试事务管理逻辑,导致回滚失效。Repository层的
@WithTransaction引发事务边界混乱FieldRepository类上的@WithTransaction会让每个Repository方法自动开启新事务,与测试类的@TestReactiveTransaction叠加后,事务边界变得模糊,最终无法触发测试后的回滚操作。
修正步骤:
- 移除测试代码中的
surroundWith(u -> Panache.withTransaction(() -> u))调用,交由@TestReactiveTransaction全权管理测试事务。 - 删除
FieldRepository类上的@WithTransaction注解。生产环境如需事务支持,可在业务方法上添加@WithTransaction,或在Repository方法内部通过Panache.withTransaction()包裹逻辑,灵活控制事务边界。
修正后的测试代码
@QuarkusTest @TestReactiveTransaction class AttributeRepositoryTest2 { @Test void shouldUpdateEntity(UniAsserter asserter) { FieldEntity entity = new FieldEntity(); var updatedValue = "updatedValue"; asserter.execute(() -> fieldRepository.persist(entity)) .assertThat(() -> fieldRepository.updatePreview(entity.id, updatedValue), fieldEntity -> Assertions.assertThat(fieldEntity) .extracting(field -> field.previewValue, field -> field.updated) .contains(updatedValue, true)); } }
内容的提问来源于stack exchange,提问作者oucem
相关产品推荐
相关产品推荐

