mongodb transaction + docker 搭建replica sets 测试

基本概念

  1. 多文档事务可以用在多个操作、集合、数据库、文档上
  2. all-or-nothing
  3. 高效的schema优先
    In most cases, multi-document transaction incurs a greater performance cost over single document writes, and the availability of multi-document transaction should not be a replacement for effective schema design.
  4. 当前版本只支持replica sets
    Multi-document transactions are available for replica sets only. Transactions for sharded clusters are scheduled for MongoDB 4.2
  5. 仅支持WiredTiger storage engine

特性兼容测试

db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )
4.0 版本执行结果如下:
{
    "featureCompatibilityVersion" : {
        "version" : "4.0"
    },
    "ok" : 1.0
}
3.4 版本执行结果如下:
{
    "ok" : 0.0,
    "errmsg" : "not authorized on admin to execute command { getParameter: 1.0, featureCompatibilityVersion: 1.0 }",
    "code" : 13,
    "codeName" : "Unauthorized"
}

Transactions and Operations

Transactions

  • You can specify read/write (CRUD) operations on existing collections. The collections can be in different databases
  • You cannot read/write to collections in the config, admin, or local databases.
  • You cannot write to system.* collections.
  • You cannot return the supported operation’s query plan (i.e. explain).
  • For cursors created outside of transactions, you cannot call getMore inside a transaction.
  • For cursors created in a transaction, you cannot call getMore outside the transaction.

Operations

Operations that affect the database catalog, such as creating or dropping a collection or an index, are not allowed in multi-document transactions.

Transactions and Security

  • If running with access control, you must have privileges for the operations in the transaction.
  • If running with auditing, operations in an aborted transaction are still audited. However, there is no audit event that indicates that the transaction aborted.

事务 与 会话

事务关联一个会话,任何时刻一个会话只能有一个事务

支持mognodb4.0的驱动版本

Java 3.8.0、Node 3.1.0、Python 3.7.0

Transactions and Locks

By default, transactions waits up to 5 milliseconds to acquire locks required by the operations in the transaction. If the transaction cannot acquire its required locks within the 5 milliseconds, the transaction aborts.

生产考虑

运行限制

默认,事务必须在1分钟内执行完成。超时会被丢弃。

获取锁限制

默认,事务没有在5毫秒内获取锁,事务失败

Pending DDL Operations and Transactions

While these pending DDL operations exist, new transactions that access the same database as the pending DDL operations cannot obtain the required locks and will abort after waiting maxTransactionLockRequestTimeoutMillis.

事务[Mongo Shell]

1. 开启session
> session = db.getMongo().startSession()
session { "id" : UUID("735ec42b-cace-41cb-a8c8-91153ff42657") }
  1. 开启事务写入
session.startTransaction()
db = session.getDatabase('test')

session.commitTransaction();
//session.abortTransaction()

docker搭建replica sets

  • ## 下载mongo 最新镜像
docker pull mongo
  • ## 查看下载的镜像
docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mongo               latest              ae68bfa1087d        14 hours ago        380MB
  • ## 启动mongod服务

第一次尝试将mongodb的数据存在宿主机

docker run  --name mongo-0  -v $PWD/db0:/data/db -p 27017:27017   -d mongo mongod --replSet rs0 --port 27017 --bind_ip localhost --dbpath /data/db --smallfiles --oplogSize 128

但是,不幸的是一直起不起来,有资料说

默认使用wiredTiger引擎,但是挂载卷不支持这个引擎,所以启动时更换默认的引擎即可,可采用指定引擎为mmapv1

本次测试事务,事务仅支持wiredTiger引擎,所以没有挂载宿主机目录。

启动三个mongod服务,分别映射到不同的端口

docker run  --name mongo-0 -p 27017:27017 -d mongo --replSet "rs0" --bind_ip_all

docker run  --name mongo-1 -p 27018:27017 -d mongo --replSet "rs0" --bind_ip_all

docker run  --name mongo-2 -p 27019:27017 -d mongo --replSet "rs0" --bind_ip_all
  • ## 查看docker容器的IP地址
docker inspect mongo-0 | findstr IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
        "IPAddress": "172.17.0.2",
  • ## 连接其中一台服务,初始化副本集
    使用客户端工具连接
rs.initiate( {
    _id : "rs0",
    members: [
       { _id: 0, host: "172.17.0.2:27017" },
       { _id: 1, host: "172.17.0.3:27017" },
       { _id: 2, host: "172.17.0.4:27017" }
    ]
 })

初始化结果:

> rs.initiate( {
...    _id : "rs0",
...    members: [
...       { _id: 0, host: "172.17.0.2:27017" },
...       { _id: 1, host: "172.17.0.3:27017" },
...       { _id: 2, host: "172.17.0.4:27017" }
...    ]
... })
{
        "ok" : 1,
        "operationTime" : Timestamp(1536246235, 1),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1536246235, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}
rs0:SECONDARY>
  • ## 使用rs.conf()查看副本集配置

测试事务

  • ## 连接进副本集
docker run --name client-rs -it mongo mongo mongodb://172.17.0.2:27017,172.17.0.3:27017,172.17.0.4:27017/rs-test?replicaSet=rs0
  • ## 建好集合
    需要注意的是在事务里面不能创建collection,所以提前建好一个:
rs0:PRIMARY> use rs-test
switched to db rs-test
rs0:PRIMARY> db.book.insert({"name":"docker in action"})
WriteResult({ "nInserted" : 1 })
rs0:PRIMARY> db.book.find()
{ "_id" : ObjectId("5b91452af5a0af9da451f044"), "name" : "docker in action" }
  • ## 开启事务,插入数据并回滚
rs0:PRIMARY> db.book.find()
{ "_id" : ObjectId("5b91452af5a0af9da451f044"), "name" : "docker in action" }
rs0:PRIMARY> session = db.getMongo().startSession()
session { "id" : UUID("5720db1a-b16a-4868-afb3-6658a3ac75fa") }
rs0:PRIMARY> db = session.getDatabase('rs-test')
rs-test
rs0:PRIMARY> session.startTransaction()
rs0:PRIMARY> db.book.insert({"name":"java in action"})
WriteResult({ "nInserted" : 1 })
rs0:PRIMARY> db.book.find()
{ "_id" : ObjectId("5b91452af5a0af9da451f044"), "name" : "docker in action" }
{ "_id" : ObjectId("5b914751f5a0af9da451f047"), "name" : "java in action" }
rs0:PRIMARY> session.abortTransaction()
rs0:PRIMARY> db.book.find()
{ "_id" : ObjectId("5b91452af5a0af9da451f044"), "name" : "docker in action" }

需要注意的是session对象的获取方式

session = db.getMongo().startSession()

以及从session取得db对象,不然事务不起作用:

db = session.getDatabase('rs-test')
  • ## 开启事务,插入数据并提交
rs0:PRIMARY> session.startTransaction()
rs0:PRIMARY> db.book.insert({"name":"python in action"})
WriteResult({ "nInserted" : 1 })
rs0:PRIMARY> db.book.find()
{ "_id" : ObjectId("5b91452af5a0af9da451f044"), "name" : "docker in action" }
{ "_id" : ObjectId("5b914693f5a0af9da451f046"), "name" : "python in action" }
rs0:PRIMARY> session.commitTransaction();
rs0:PRIMARY> db.book.find()
{ "_id" : ObjectId("5b91452af5a0af9da451f044"), "name" : "docker in action" }
{ "_id" : ObjectId("5b914693f5a0af9da451f046"), "name" : "python in action" }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MongoDB 7.0中,你可以通过以下步骤设置账号密码: 1. 下载并安装MongoDB 7.0版本。 2. 打开终端或命令提示符,进入MongoDB的安装目录。 3. 启动MongoDB服务。在终端中输入以下命令: ```shell ./mongod ``` 4. 打开另一个终端或命令提示符,进入MongoDB的安装目录。 5. 连接到MongoDB服务器。在终端中输入以下命令: ```shell ./mongo ``` 6. 创建一个管理员用户。在MongoDB Shell中输入以下命令: ```shell use admin db.createUser( { user: "admin", pwd: "admin123", roles: [ { role: "root", db: "admin" } ] } ) ``` 这将创建一个名为admin的数据库,并在该数据库中创建一个名为admin的用户,密码为admin123,并赋予该用户root角色。 7. 退出MongoDB Shell。在MongoDB Shell中输入以下命令: ```shell quit() ``` 8. 停止MongoDB服务。在终端中按下Ctrl+C键停止MongoDB服务。 9. 修改MongoDB配置文件。打开MongoDB的配置文件(通常位于安装目录的/etc/mongod.conf或/data/db/mongod.conf),找到并取消注释以下行: ```shell security: authorization: enabled ``` 10. 保存并关闭配置文件。 11. 启动MongoDB服务。在终端中输入以下命令: ```shell ./mongod ``` 12. 打开另一个终端或命令提示符,进入MongoDB的安装目录。 13. 连接到MongoDB服务器。在终端中输入以下命令: ```shell ./mongo -u admin -p admin123 --authenticationDatabase admin ``` 这将使用管理员用户连接到MongoDB服务器。 14. 现在你可以使用账号密码进行MongoDB的操作了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值