Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在两个不同的ReactiveMongoRepository';在使用Spring数据MongoDB的事务中?_Java_Spring_Mongodb_Spring Boot_Spring Data Mongodb Reactive - Fatal编程技术网

Java 在两个不同的ReactiveMongoRepository';在使用Spring数据MongoDB的事务中?

Java 在两个不同的ReactiveMongoRepository';在使用Spring数据MongoDB的事务中?,java,spring,mongodb,spring-boot,spring-data-mongodb-reactive,Java,Spring,Mongodb,Spring Boot,Spring Data Mongodb Reactive,使用Spring Data MongoDB的反应式编程模型时,可以执行如下事务: Mono result=template.inTransaction() .execute(action->action.remove(查询(其中(“id”).is(“step-1”)),step.class)); 但是Spring Data MongoDB也支持“反应式存储库”,例如: public interface PersonRepository扩展了ReactiveMongoRepository 通过定

使用Spring Data MongoDB的反应式编程模型时,可以执行如下事务:

Mono result=template.inTransaction()
.execute(action->action.remove(查询(其中(“id”).is(“step-1”)),step.class));
但是Spring Data MongoDB也支持“反应式存储库”,例如:

public interface PersonRepository扩展了ReactiveMongoRepository
通过定位线查找的流量(点位置、距离);
}

public interface CarRepository扩展了ReactiveMongoRepository
通量查找年份(整数年);
}

我的问题是,考虑到您有
ReactiveMongoRepository
,您能否以某种方式利用MongoDB事务,例如在同一事务中同时插入
Person
CarRepository
(在本例中使用
PersonRepository
)?如果是这样的话,您是如何做到的?

我也一直在努力寻找解决方案,为Mongo DB&Spring Boot的反应式事务性支持提供解决方案

但幸运的是我自己发现了。虽然谷歌提供的东西很少有帮助,但这些都是非反应性的

重要注意事项-对于Spring boot 2.2.x,它工作得很好,但是对于Spring boot 2.3.x,它还有一些其他问题,包括内部重写和更改

  • 您需要使用ReactiveMongoTransactionManager以及ReactiveMongoDatabaseFactory,最后的大部分细节,还需要共享相同的代码repo

  • 为了让mongo db支持事务,我们需要确保db应该在副本模式下运行

    我们为什么需要它?因为否则会出现如下错误:-

    此客户端所连接的MongoDB群集不支持会话

相关说明如下所示:-

  • 使用docker-compose.yml运行基于docker compose的mongo db服务器,如下所示:-
  • 图像出现后,执行命令(此处localmongo\u docker是容器的名称):-
  • 复制并粘贴下面的命令,然后执行该命令
  • 然后通过输入退出退出退出执行
  • 重要-代码回购可在我的github上找到-

    代码的重要注释如下:-

    • config包中的MongoConfiguration类是使事务正常工作的重要部分,可以使用到配置类的链接

    • 主要部分是Bean

       @Bean
       ReactiveMongoTransactionManager transactionManager(ReactiveMongoDatabaseFactory dbFactory) {
           return new ReactiveMongoTransactionManager(dbFactory);
       }
      
    • 为了检查代码事务性需求的工作情况,您可以通过服务包中的类UserService进行检查

    如果链接对某人不起作用,则共享代码:-

    配置和bean内部

    @Configuration
    public class MongoConfiguration extends AbstractMongoClientConfiguration {
    
        @Autowired
        private MongoProperties mongoProperties;
    
        @Bean
        ReactiveMongoTransactionManager transactionManager(ReactiveMongoDatabaseFactory dbFactory) {
            return new ReactiveMongoTransactionManager(dbFactory);
        }
    
        @Override
        protected String getDatabaseName() {
            return mongoProperties.getDatabase();
        }
    
        @Override
        public MongoClient mongoClient() {
            return MongoClients.create(mongoProperties.getUri());
        }
    }
    
    @Getter
    @Setter
    @Accessors(chain = true)
    @Document(collection = "roles")
    @TypeAlias("role")
    public class Role implements Persistable<String> {
    
        @Id
        private String id;
    
        @Field("role_name")
        @Indexed(unique = true)
        private String role;
    
        @CreatedDate
        private ZonedDateTime created;
    
        @LastModifiedDate
        private ZonedDateTime updated;
    
        private Boolean deleted;
    
        private Boolean enabled;
    
        @Override
        @JsonIgnore
        public boolean isNew() {
            if(getCreated() == null)
                return true;
            else
                return false;
        }
    }
    
    @Getter
    @Setter
    @Accessors(chain = true)
    @Document(collection = "users")
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @TypeAlias("user")
    public class User implements Persistable<String> {
    
        @Id()
        private String id;
    
        @Field("username")
        @Indexed(unique = true)
        @JsonProperty("username")
        private String userName;
    
        @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
        private String password;
    
        @CreatedDate
        private ZonedDateTime created;
    
        @LastModifiedDate
        private ZonedDateTime updated;
    
        private Boolean deleted;
    
        private Boolean enabled;
    
        @DBRef(lazy = true)
        @JsonProperty("roles")
        private List<Role> roles = new ArrayList();
    
        @Override
        @JsonIgnore
        public boolean isNew() {
            if(getCreated() == null)
                return true;
            else
                return false;
        }
    }
    
    @Getter
    @Setter
    @Accessors(chain = true)
    @Document(collection = "user_profiles")
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @TypeAlias("user_profile")
    public class UserProfile implements Persistable<String> {
    
        @Id
        private String id;
    
        @Indexed(unique = true)
        private String mobile;
    
        @Indexed(unique = true)
        private String email;
    
        private String address;
    
        private String firstName;
    
        private String lastName;
    
        @DBRef
        private User user;
    
        @CreatedDate
        private ZonedDateTime created;
    
        @LastModifiedDate
        private ZonedDateTime updated;
    
        private Boolean deleted;
    
        private Boolean enabled;
    
        @Override
        @JsonIgnore
        public boolean isNew() {
            if(getCreated() == null)
                return true;
            else
                return false;
        }
    
    }
    
    application.properties(与mongo db相关)

    文档类

    @Configuration
    public class MongoConfiguration extends AbstractMongoClientConfiguration {
    
        @Autowired
        private MongoProperties mongoProperties;
    
        @Bean
        ReactiveMongoTransactionManager transactionManager(ReactiveMongoDatabaseFactory dbFactory) {
            return new ReactiveMongoTransactionManager(dbFactory);
        }
    
        @Override
        protected String getDatabaseName() {
            return mongoProperties.getDatabase();
        }
    
        @Override
        public MongoClient mongoClient() {
            return MongoClients.create(mongoProperties.getUri());
        }
    }
    
    @Getter
    @Setter
    @Accessors(chain = true)
    @Document(collection = "roles")
    @TypeAlias("role")
    public class Role implements Persistable<String> {
    
        @Id
        private String id;
    
        @Field("role_name")
        @Indexed(unique = true)
        private String role;
    
        @CreatedDate
        private ZonedDateTime created;
    
        @LastModifiedDate
        private ZonedDateTime updated;
    
        private Boolean deleted;
    
        private Boolean enabled;
    
        @Override
        @JsonIgnore
        public boolean isNew() {
            if(getCreated() == null)
                return true;
            else
                return false;
        }
    }
    
    @Getter
    @Setter
    @Accessors(chain = true)
    @Document(collection = "users")
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @TypeAlias("user")
    public class User implements Persistable<String> {
    
        @Id()
        private String id;
    
        @Field("username")
        @Indexed(unique = true)
        @JsonProperty("username")
        private String userName;
    
        @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
        private String password;
    
        @CreatedDate
        private ZonedDateTime created;
    
        @LastModifiedDate
        private ZonedDateTime updated;
    
        private Boolean deleted;
    
        private Boolean enabled;
    
        @DBRef(lazy = true)
        @JsonProperty("roles")
        private List<Role> roles = new ArrayList();
    
        @Override
        @JsonIgnore
        public boolean isNew() {
            if(getCreated() == null)
                return true;
            else
                return false;
        }
    }
    
    @Getter
    @Setter
    @Accessors(chain = true)
    @Document(collection = "user_profiles")
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @TypeAlias("user_profile")
    public class UserProfile implements Persistable<String> {
    
        @Id
        private String id;
    
        @Indexed(unique = true)
        private String mobile;
    
        @Indexed(unique = true)
        private String email;
    
        private String address;
    
        private String firstName;
    
        private String lastName;
    
        @DBRef
        private User user;
    
        @CreatedDate
        private ZonedDateTime created;
    
        @LastModifiedDate
        private ZonedDateTime updated;
    
        private Boolean deleted;
    
        private Boolean enabled;
    
        @Override
        @JsonIgnore
        public boolean isNew() {
            if(getCreated() == null)
                return true;
            else
                return false;
        }
    
    }
    
    角色类别

    @Configuration
    public class MongoConfiguration extends AbstractMongoClientConfiguration {
    
        @Autowired
        private MongoProperties mongoProperties;
    
        @Bean
        ReactiveMongoTransactionManager transactionManager(ReactiveMongoDatabaseFactory dbFactory) {
            return new ReactiveMongoTransactionManager(dbFactory);
        }
    
        @Override
        protected String getDatabaseName() {
            return mongoProperties.getDatabase();
        }
    
        @Override
        public MongoClient mongoClient() {
            return MongoClients.create(mongoProperties.getUri());
        }
    }
    
    @Getter
    @Setter
    @Accessors(chain = true)
    @Document(collection = "roles")
    @TypeAlias("role")
    public class Role implements Persistable<String> {
    
        @Id
        private String id;
    
        @Field("role_name")
        @Indexed(unique = true)
        private String role;
    
        @CreatedDate
        private ZonedDateTime created;
    
        @LastModifiedDate
        private ZonedDateTime updated;
    
        private Boolean deleted;
    
        private Boolean enabled;
    
        @Override
        @JsonIgnore
        public boolean isNew() {
            if(getCreated() == null)
                return true;
            else
                return false;
        }
    }
    
    @Getter
    @Setter
    @Accessors(chain = true)
    @Document(collection = "users")
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @TypeAlias("user")
    public class User implements Persistable<String> {
    
        @Id()
        private String id;
    
        @Field("username")
        @Indexed(unique = true)
        @JsonProperty("username")
        private String userName;
    
        @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
        private String password;
    
        @CreatedDate
        private ZonedDateTime created;
    
        @LastModifiedDate
        private ZonedDateTime updated;
    
        private Boolean deleted;
    
        private Boolean enabled;
    
        @DBRef(lazy = true)
        @JsonProperty("roles")
        private List<Role> roles = new ArrayList();
    
        @Override
        @JsonIgnore
        public boolean isNew() {
            if(getCreated() == null)
                return true;
            else
                return false;
        }
    }
    
    @Getter
    @Setter
    @Accessors(chain = true)
    @Document(collection = "user_profiles")
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @TypeAlias("user_profile")
    public class UserProfile implements Persistable<String> {
    
        @Id
        private String id;
    
        @Indexed(unique = true)
        private String mobile;
    
        @Indexed(unique = true)
        private String email;
    
        private String address;
    
        private String firstName;
    
        private String lastName;
    
        @DBRef
        private User user;
    
        @CreatedDate
        private ZonedDateTime created;
    
        @LastModifiedDate
        private ZonedDateTime updated;
    
        private Boolean deleted;
    
        private Boolean enabled;
    
        @Override
        @JsonIgnore
        public boolean isNew() {
            if(getCreated() == null)
                return true;
            else
                return false;
        }
    
    }
    
    UserProfileApisController

    @Slf4j
    @RestController
    @RequestMapping("/apis/user/profile")
    public class UserProfileApisController {
    
        @Autowired
        private UserService userService;
    
        @PostMapping
        public Mono<UserProfile> saveUserProfile(final @RequestBody UserRequest userRequest) {
            return userService.saveUserAndItsProfile(userRequest);
        }
    
    }
    
    @Slf4j
    @RestController
    @请求映射(“/api/user/profile”)
    公共类UserProfileApisController{
    @自动连线
    私人用户服务;
    @邮戳
    公共Mono saveUserProfile(final@RequestBody UserRequest UserRequest){
    返回userService.saveUserAndItsProfile(userRequest);
    }
    }
    
    只是对公认的MongoDB副本集初始化答案的补充

  • 如果需要一个非固定端口单副本集进行测试,则可以使用该副本集封装此类初始化:
  • final MongoDBContainer MongoDBContainer=新的MongoDBContainer(“mongo:4.2.8”);
    
    我们可以通过“mongoDBContainer.start()”启动它,并通过“try with resources”或“mongoDBContainer.stop()”停止它

  • 如果需要一个非固定端口多节点副本集来测试复杂的生产问题,他们可能会使用,例如:
  • 试试看(
    //创建PSA MongoDBreplication集,然后自动关闭
    最终MongoDbReplicaSet MongoDbReplicaSet=MongoDbReplicaSet.builder()
    //具有2个工作节点
    .replicaSetNumber(2)
    //使用仲裁节点
    .addArbiter(正确)
    //为每个节点创建代理以模拟网络分区
    .addToxiproxy(true)
    .build()
    ) {
    //开始吧
    mongoDbReplicaSet.start();
    assertNotNull(mongoDbReplicaSet.getReplicaSetUrl());
    //做一些测试
    }
    
    有关于这个伴侣的帮助吗@JohanSorry,但我不记得我找到了解决方案。幸运的是,在给你发消息后,我发现了这一点,我很快会与你分享。看到答案了吗below@Johan我还在编辑的过程中。但是请仔细阅读我在回答中分享的细节谢谢@kakabali,但是您能在这里包含代码示例的要点吗?我认为这是stackoverflow答案的习惯,因为远程链接可能不再存在。
    @Slf4j
    @RestController
    @RequestMapping("/apis/user/profile")
    public class UserProfileApisController {
    
        @Autowired
        private UserService userService;
    
        @PostMapping
        public Mono<UserProfile> saveUserProfile(final @RequestBody UserRequest userRequest) {
            return userService.saveUserAndItsProfile(userRequest);
        }
    
    }