1.MongoDB集群搭建
- 先学会搭建单机MongoDB。详情参考MongoDb搭建及使用。
replicSet准备。
新建replicSet文件夹。文件夹下有如下文件。
D:\dev\MongoDB\replicSet λ ls rs27001/ rs27002/ rs27003/
D:\dev\MongoDB\replicSet\rs27001 λ ls db/ mongod.exe* rs27001.conf
replicSet下的三个子文件夹目录结构一致。
/db
为空文件夹,用来存储数据。mongod.exe
是mongodb的启动程序,从bin
目录拷过来的。rs27001.conf
是配置文件。配置文件如下:port=27001 bind_ip=qiqiang01 dbpath=./db replSet=mongoSetName
ip地址是我的本地地址,我修改了本地的hosts文件,用
qiqiang01
,qiqiang02
和qiqiang03
指向127.0.0.1
。启动三个节点。
.\mongod.exe -f rs27001.conf
进入
bin
目录,用客户端连接工具进入mongo。λ .\mongo --port 27001
初始化副本集。
> rs.initiate() { "info2" : "no configuration specified. Using a default configuration for the set", "me" : "qiqiang01:27001", "ok" : 1, "operationTime" : Timestamp(1535679979, 1), "$clusterTime" : { "clusterTime" : Timestamp(1535679979, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } }
查看状态
mongoSetName:SECONDARY> rs.status() { "set" : "mongoSetName", "date" : ISODate("2018-08-31T01:47:06.861Z"), "myState" : 1, "term" : NumberLong(1), "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1535680021, 1), "t" : NumberLong(1) }, "readConcernMajorityOpTime" : { "ts" : Timestamp(1535680021, 1), "t" : NumberLong(1) }, "appliedOpTime" : { "ts" : Timestamp(1535680021, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(1535680021, 1), "t" : NumberLong(1) } }, "lastStableCheckpointTimestamp" : Timestamp(1535679981, 2), "members" : [ { "_id" : 0, "name" : "qiqiang01:27001", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 92, "optime" : { "ts" : Timestamp(1535680021, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2018-08-31T01:47:01Z"), "syncingTo" : "", "syncSourceHost" : "", "infoMessage" : "could not find member to sync from", "electionTime" : Timestamp(1535679979, 2), "electionDate" : ISODate("2018-08-31T01:46:19Z"), "configVersion" : 1, "self" : true, "lastHeartbeatMessage" : "" } ], "ok" : 1, "operationTime" : Timestamp(1535680021, 1), "$clusterTime" : { "clusterTime" : Timestamp(1535680021, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } }
添加新成员至副本集
mongoSetName:PRIMARY> rs.add("qiqiang02:27002") { "ok" : 1, "operationTime" : Timestamp(1535680549, 1), "$clusterTime" : { "clusterTime" : Timestamp(1535680549, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } }
再次执行
rs.status()
可看到members里面有两个节点了。进入在从节点(27002和27003) 设置节点状态为 OK。
mongoSetName:SECONDARY> rs.slaveOk()
2.SpringBoot实现MongoDB事务。
Springboot与mongoDB的集成看上一篇文章MongoDb搭建及使用。
mongoDB配置类
@Configuration public class MongoConfig extends AbstractMongoConfiguration{ @Bean public MongoTransactionManager transactionManager(MongoDbFactory dbFactory) { return new MongoTransactionManager(dbFactory); } @Override public MongoClient mongoClient() { //端口号和ip return new MongoClient("qiqiang01",27001); } @Override protected String getDatabaseName() { //库名 return "test"; } }
事务测试
@Service @Slf4j public class UserServiceImpl implements UserService { private final UserRepository userRepository; @Autowired public UserServiceImpl(UserRepository userRepository) { this.userRepository = userRepository; } @Override @Transactional(rollbackFor = Throwable.class) public void save(UserEntity userEntity) throws Exception { UserEntity entity = userRepository.save(userEntity); log.info("成功插入数据{}"+entity); throw new Exception("事务测试异常"); } }
在启动类上加上事务注解
@EnableTransactionManagement
。
3.说明
- 本篇文章所用的Springboot版本是
2.1.0.M2
,是里程碑版本,不是正式版,后续会有变动。 - 在系统配置文件中设置mongo的参数在处理事务时会报错,必须在MongoConfig里配置参数,不处理事务的可以正常使用。这个原因我还没有找到。