Springboot Mongo db方法不回滚事务

发布于 2025-01-11 15:01:26 字数 3694 浏览 0 评论 0原文

您好,我在代码库中使用 2 个 mongo 模板 我的代码使用 mongo 模板和 Spring 存储库 class.save() 将数据保存在 mongo db 中。在具有 @Transactional 的方法中,即使代码执行中发生一些错误,也不会回滚数据库更改。 下面是我的 mongoconfig 配置的片段

@Configuration
@EnableMongoAuditing
@EnableMongoRepositories
public class MongoConfig extends AbstractMongoClientConfiguration {

    @Value("${common.db.name}")
    private String dbName;

    @Value("${SPRING_DATA_MONGODB_URI}")
    private String dbUrl;

    public String getDbName() {
        return dbName;
    }

    public void setDbName(String dbName) {
        this.dbName = dbName;
    }
    @Override
    protected String getDatabaseName() {
        return dbName;
    }

    /**
     *  Below bean is created as we want to make our code transactional.
     * @param dbFactory
     * @return
     */
    @Bean(name="primaryTransactionManager")
    MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
        MongoTransactionManager transactionManager = new MongoTransactionManager(dbFactory);
        transactionManager.setRollbackOnCommitFailure(true);
        return transactionManager;
    }

    @Override
    public MongoClient mongoClient() {
        ConnectionString connectionString = new ConnectionString(dbUrl);
        MongoClientSettings mongoClientSettings = MongoClientSettings.builder().applyConnectionString(connectionString).build();
        return MongoClients.create(mongoClientSettings);
    }

    @Bean(name="primaryMongoTemplate")
    public MongoTemplate mongoTemplate() {
        return new MongoTemplate(mongoClient(), getDbName());
    }
}

@Configuration
@EnableMongoRepositories
public class SecondaryMongoConfig {

    @Value("${common.secondary.db.name}")
    private String dbName;

    @Value("${COMMON_SECONDARY_SPRING_DATA_MONGODB_URI}")
    private String mongoDBURI;

    public String getMongoDBURI() {
        return mongoDBURI;
    }

    public void setMongoDBURI(String mongoDBURI) {
        this.mongoDBURI = mongoDBURI;
    }

    public String getDbName() {
        return dbName;
    }

    public void setDbName(String dbName) {
        this.dbName = dbName;
    }

    /**
     * Below bean is created as we want to make our code transactional.
     * @param dbFactory
     * @return
     */
    @Bean(name="secondaryTransactionManager")
    MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
        MongoTransactionManager transactionManager = new MongoTransactionManager(dbFactory);
        transactionManager.setRollbackOnCommitFailure(true);
        return new MongoTransactionManager(dbFactory);
    }
    
    @Bean(name="secondaryMongoClient")
    public MongoClient secondaryMongoClient() {
        ConnectionString connectionString = new ConnectionString(getMongoDBURI());
        MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
                .applyConnectionString(connectionString)
                .build();

        return MongoClients.create(mongoClientSettings);
    }

    @Bean(name="secondaryMongoTemplate")
    public MongoTemplate secondaryMongoTemplate() {
        return new MongoTemplate(secondaryMongoClient(), getDbName());
    }
}

下面是我用 @Transactional 注释的方法的示例代码片段

    @Override
    @Transactional(transactionManager = "primaryTransactionManager",rollbackFor = {Exception.class})
    public String addNewRecipe() throws Exception{
        RecipesDAO recipesDao = new RecipesDAO();
        recipesDao.setResourceId(UUID.randomUUID().toString());
        recipeRepository.save(recipesDao);
        throw new Exception();
    //  return "dummy";
    }

Hi i am using 2 mongo template in my codebase
and my code saves data in mongo db using both mongo template and Spring repository class.save() .In methods which has @Transactional doesnt rollback DB changes even if some error occurs in code execution.
Below is the snippet of my mongoconfig configurations

@Configuration
@EnableMongoAuditing
@EnableMongoRepositories
public class MongoConfig extends AbstractMongoClientConfiguration {

    @Value("${common.db.name}")
    private String dbName;

    @Value("${SPRING_DATA_MONGODB_URI}")
    private String dbUrl;

    public String getDbName() {
        return dbName;
    }

    public void setDbName(String dbName) {
        this.dbName = dbName;
    }
    @Override
    protected String getDatabaseName() {
        return dbName;
    }

    /**
     *  Below bean is created as we want to make our code transactional.
     * @param dbFactory
     * @return
     */
    @Bean(name="primaryTransactionManager")
    MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
        MongoTransactionManager transactionManager = new MongoTransactionManager(dbFactory);
        transactionManager.setRollbackOnCommitFailure(true);
        return transactionManager;
    }

    @Override
    public MongoClient mongoClient() {
        ConnectionString connectionString = new ConnectionString(dbUrl);
        MongoClientSettings mongoClientSettings = MongoClientSettings.builder().applyConnectionString(connectionString).build();
        return MongoClients.create(mongoClientSettings);
    }

    @Bean(name="primaryMongoTemplate")
    public MongoTemplate mongoTemplate() {
        return new MongoTemplate(mongoClient(), getDbName());
    }
}

@Configuration
@EnableMongoRepositories
public class SecondaryMongoConfig {

    @Value("${common.secondary.db.name}")
    private String dbName;

    @Value("${COMMON_SECONDARY_SPRING_DATA_MONGODB_URI}")
    private String mongoDBURI;

    public String getMongoDBURI() {
        return mongoDBURI;
    }

    public void setMongoDBURI(String mongoDBURI) {
        this.mongoDBURI = mongoDBURI;
    }

    public String getDbName() {
        return dbName;
    }

    public void setDbName(String dbName) {
        this.dbName = dbName;
    }

    /**
     * Below bean is created as we want to make our code transactional.
     * @param dbFactory
     * @return
     */
    @Bean(name="secondaryTransactionManager")
    MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
        MongoTransactionManager transactionManager = new MongoTransactionManager(dbFactory);
        transactionManager.setRollbackOnCommitFailure(true);
        return new MongoTransactionManager(dbFactory);
    }
    
    @Bean(name="secondaryMongoClient")
    public MongoClient secondaryMongoClient() {
        ConnectionString connectionString = new ConnectionString(getMongoDBURI());
        MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
                .applyConnectionString(connectionString)
                .build();

        return MongoClients.create(mongoClientSettings);
    }

    @Bean(name="secondaryMongoTemplate")
    public MongoTemplate secondaryMongoTemplate() {
        return new MongoTemplate(secondaryMongoClient(), getDbName());
    }
}

Below is my sample code snippet of method annoted with @Transactional

    @Override
    @Transactional(transactionManager = "primaryTransactionManager",rollbackFor = {Exception.class})
    public String addNewRecipe() throws Exception{
        RecipesDAO recipesDao = new RecipesDAO();
        recipesDao.setResourceId(UUID.randomUUID().toString());
        recipeRepository.save(recipesDao);
        throw new Exception();
    //  return "dummy";
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

失与倦" 2025-01-18 15:01:29

是我必须使用的代码片段,以便在代码执行流程中发生异常时回滚事务

@Bean(name="primaryMongoTemplate")
    public MongoTemplate mongoTemplate() {
        MongoTemplate primaryMongoTemplate = new MongoTemplate(mongoClient(), getDbName());
        primaryMongoTemplate.setSessionSynchronization(SessionSynchronization.ALWAYS);
        return primaryMongoTemplate;
    }

    @Bean(name="secondaryMongoTemplate")
    public MongoTemplate secondaryMongoTemplate() {
        MongoTemplate secondaryMongoTemplate = new MongoTemplate(secondaryMongoClient(), getDbName());
        secondaryMongoTemplate.setSessionSynchronization(SessionSynchronization.ALWAYS);
        return secondaryMongoTemplate;
    }

在检查了我的类 MongoConfig.java 中使用的类的每个方法后,我得到了解决方案。下面 无论何时创建新的或修改 mongodb 文档的代码都存在,例如用于立即创建或修改文档的 somerepository.save(s) 代码,但通过添加primaryMongoTemplate.setSessionSynchronization(SessionSynchronization.ALWAYS);secondaryMongoTemplate.setSessionSynchronization(SessionSynchronization.ALWAYS);
代码等待完整的执行流程,并检查该执行流程中是否发生异常。只有在检查执行流程中没有发生异常后,它才会创建或修改文档。

I got solution after checking each and every method of classes used in my class MongoConfig.java.Below is the snippet of code which i had to use in order to rollback transactions when exceptions occured in code execution flow

@Bean(name="primaryMongoTemplate")
    public MongoTemplate mongoTemplate() {
        MongoTemplate primaryMongoTemplate = new MongoTemplate(mongoClient(), getDbName());
        primaryMongoTemplate.setSessionSynchronization(SessionSynchronization.ALWAYS);
        return primaryMongoTemplate;
    }

    @Bean(name="secondaryMongoTemplate")
    public MongoTemplate secondaryMongoTemplate() {
        MongoTemplate secondaryMongoTemplate = new MongoTemplate(secondaryMongoClient(), getDbName());
        secondaryMongoTemplate.setSessionSynchronization(SessionSynchronization.ALWAYS);
        return secondaryMongoTemplate;
    }

Earlier wherever code of creating new or modifying mongodb docs was there like say somerepository.save(s) code used to create or modify documents immedialtely but by adding primaryMongoTemplate.setSessionSynchronization(SessionSynchronization.ALWAYS); and secondaryMongoTemplate.setSessionSynchronization(SessionSynchronization.ALWAYS);
code waits for complete execution flow and checks if any exception occured in this execution flow.It creates or modifies documents only after checking no exception occured in execution flow.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文