Spring Data MongoDB @Transactional无法正常工作?

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

我已经在下面建立了maven依赖性和配置

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
@Configuration
@EnableMongoAuditing
public class MongoConfig {

    @Bean
    MongoTransactionManager transactionManager(MongoDbFactory mongoDbFactory) {
        return new MongoTransactionManager(mongoDbFactory);
    }
}

Updated:我采用了建议的解决方案,用@Transactional创建一个bean,并将其注入到我的测试类中。下面是我创建的服务bean:

@Service
@Transactional
@RequiredArgsConstructor
public class MongoTransactionService {

    private final UserRepo userRepo;

    public void boundToFail() throws RuntimeException {
        userRepo.save(User.builder().id("1").build());
        throw new RuntimeException();
    }

}

和测试类,我在其中注入了MongoTransactionService的bean:

@DataMongoTest(excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class,
        includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = MongoTransactionService.class))
@ExtendWith(SpringExtension.class)
class MongoTransactionServiceTest {

    @Autowired
    UserRepo userRepo;

    @Autowired
    MongoTransactionService mongoTransactionService;

    @Test
    void testTransactional() {
        try {
            mongoTransactionService.boundToFail();
        } catch (Exception e) {
            // do something
        }
        val user = userRepo.findById("1").orElse(null);
        assertThat(user).isNull();
    }

}

我期望对boundToFail()的调用会引发RuntimeException,该调用将回滚已保存的用户,但是该用户在调用后仍会保留在数据库中。

spring-data spring-data-mongodb
1个回答
1
投票

[@Transactional需要使用单独的Spring bean的public方法,因为通过使用包含与事务基础结构交互的拦截器的代理来包装目标对象来实现事务逻辑,从而实现了事务逻辑。

您的示例遇到两个问题:

  1. 测试本身不是Spring bean。即boundToFail(…)没有添加任何交易行为。 @Transactional可以用在JUnit测试方法上,但是它控制着测试的事务行为。最显着的是,回滚事务以确保测试中对数据存储所做的更改不会影响其他测试。请参阅参考文档的this section

  2. 即使将事务逻辑应用于boundToFail(…),对该方法的本地方法调用也永远不会触发该方法,因为它不会传递正在应用该方法的代理。在the reference documentation中有更多相关信息。

您的问题的解决方案是创建一个单独的带有@Transactional批注的Spring bean,将其注入到您的测试用例中并从测试中调用该方法。

© www.soinside.com 2019 - 2024. All rights reserved.