【mongo事务】使用docker-compose启动mongo,‘单副本模式‘实现支持事务。

想要mongo支持事务的首要条件是mongo版本4.x 以上,且为复制集模式。由于很多时候使用mongo都不需要部署多副本,但是想支持事务,所以可以使用‘单副本模式’,既能保证mongo实例只有一个,又是复制集模式。
本文使用mongo5.0.8作为样例。

本文只是日常遇到问题的小记,如有错误,欢迎指出。

首先给出docker-compose.yml
version: '3.0'
services:
  mongo:
    image: mongo:5.0.8
    restart: unless-stopped
    container_name: mongodb
    command: --replSet rs0 --bind_ip_all --keyFile /data/mongodb/keyFile
    environment:
      TZ: 'Asia/Shanghai'
      #用户名密码
      MONGO_INITDB_ROOT_USERNAME: 'admin'
      MONGO_INITDB_ROOT_PASSWORD: 'password'
    ports:
      - 27017:27017
    volumes:
      - ./mongodb/data:/data/db
      - ./mongodb/keyFile:/data/mongodb/keyFile
准备keyFile

本人粗略测试在4.x版本不需要使用keyFile,但是在5.x版本是必须要KeyFile的,不然会报 “BadValue: security.keyFile is required when authorization is enabled with replica sets”
在这里插入图片描述

生成keyFile
openssl rand -base64 128 > ./mongodb/keyFile

其中 ./mongodb/keyFile 是指定生成文件的名字以及在哪一个文件夹下

设置权限以及所属用户

keyFile文件的权限必须为600,如果权限太大,启动时会报“error opening file: /data/mongodb/keyFile: bad file”
在这里插入图片描述
当权限改为600以后还需要把keyFile文件的所属用户和用户组改为mongodb不然在启动时会报"permissions on /data/mongodb/keyFile are too open"
在这里插入图片描述
由于使用容器启动所以需要把keyFile文件的所属用户和用户组 改为999,这样容器会自动把keyFile文件的所属用户和用户组改为mongodb。

sudo chmod 600 keyFile
sudo chown 999:999 keyFile

容器外
在这里插入图片描述
容器里

在这里插入图片描述
当keyFile文件准备好以后,就可以根据上面的docker-compose.yml启动容器。

初始化

容器启动后这时mongo还不能使用,还需要进入容器内初始化复制集。
进入容器

docker exec -it mongodb /bin/bash

用刚刚设置的用户名密码进入mongo

mongo -u admin --authenticationDatabase admin

在这里插入图片描述

执行初始化

rs.initiate()

显示一下就说明成功了
在这里插入图片描述
到这mongo就算是启动完成了。

spring boot项目配置

要想实现事务还需要在项目中进行配置

spring boot 版本: 2.1.6.RELEASE

@Configuration
@Slf4j
public class MongoTransactionConfig {
    @Bean
    MongoTransactionManager transactionManager(MongoDbFactory factory){
        log.warn("开启mongo事务");
        return new MongoTransactionManager(factory);
    }
}

在spring boot高版本中MongoDbFactory被弃用需要换成MongoDatabaseFactory

spring boot 版本:2.6.1

@Configuration
@Slf4j
public class MongoTransactionConfig {
    @Bean
    MongoTransactionManager transactionManager(MongoDatabaseFactory factory){
        log.warn("开启mongo事务");
        return new MongoTransactionManager(factory);
    }
}

添加配置类以后只需要在方法上加入@Transactional注解就可以实现mongo事务了。


!!!新增!!!
很多时候我们会保留挂载出来的数据,重新构建容器,由于docker在每次构建新容器时都会为容器随机分配一个hostname。但因为我们还是使用上一个容器挂载出来的数据,这就导致mongo副本集配置的hostname还是上一个容器,这就导致新启动的mongo不能用。因此我们只需要改变mongo副本集配置的hostname,就能解决这个问题

当我们启动mongo后直接连接会报这个错。
在这里插入图片描述

我们首先进入容器,查看当前容器的hostname
在这里插入图片描述
使用上面提到的方式,使用admin账号登陆mongo,查看config

rs.config()

在这里插入图片描述
正如上述所说config里的hostname与当前容器的不一样

方法1:更改hostname

1.获取副本集配置

config=rs.conf()

2.可以根据上面配置json的格式可以知道hostname的位置,从而对他进行重新赋值(将host改为当前容器的host)

config.members[0].host="c3e9261f8a04:27017"

3.最后更新config

rs.reconfig(config, {force : true})

在这里插入图片描述
改完以后mongo就能正常启动了

方法2:在yaml中指定hostname
version: '3.0'
services:
  mongo:
  	hostname: mongo501
    image: mongo:5.0.8
    restart: unless-stopped
    container_name: mongodb
    command: --replSet rs0 --bind_ip_all --keyFile /data/mongodb/keyFile
    environment:
      TZ: 'Asia/Shanghai'
      #用户名密码
      MONGO_INITDB_ROOT_USERNAME: 'admin'
      MONGO_INITDB_ROOT_PASSWORD: 'password'
    ports:
      - 27017:27017
    volumes:
      - ./mongodb/data:/data/db
      - ./mongodb/keyFile:/data/mongodb/keyFile

这样的话每次新建的容器的hostname都是同一个了。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值