【MongoDB】4.0版本事务上手测试

事务上手测试

基础:

原来3版本的只能叫单文档事务,即针对行的事务。所以没必要显式提供调用,多文档事务由于有损耗,照顾到性能的需求,提供了事务开启关闭的接口。
多行,多集合,多库之间读肯定会牵扯到一致性读,所以多文档事务肯定是有必要的。
4.2版本可能会支持分片系统多文档事务,4.0的多文档事务最多只面向复制集

准备

集合:

use dba;
[10.240.129.36:[email protected]]> db.coll_2.find()
[10.240.129.36:[email protected]]> db.coll_1.find()
{ "_id" : ObjectId("5b371e120d6160b73a9fcee6"), "test" : true }
{ "_id" : ObjectId("5b371e6d0d6160b73a9fcee7"), "test" : true }

精简命令:


// 显式开启一个会话(难道通过shell链接来本身不就是会话吗?)
session=db.getMongo().startSession()
// 显式开启事务
session.startTransaction()
// 获取表对象
coll_1=session.getDatabase(‘dba‘).coll_1
coll_2=session.getDatabase(‘dba‘).coll_2;
// 使用表对象的插入函数进行插入
coll_1.insertOne({‘not_test‘:false})
coll_2.insertOne({‘not_test‘:false})
// 提交事务
session.commitTransaction()
// 回滚事务
session.abortTransaction()
// 检查事务准确性
db.coll_1.find()
db.coll_2.find()

超时参数怎么设置?

默认事务生命周期为60秒,超出后会被自动清理

// The minimum value for transactionLifetimeLimitSeconds is 1 second.
db.adminCommand( { setParameter: 1, transactionLifetimeLimitSeconds: 30 } )
// You can also set parameter transactionLifetimeLimitSeconds at startup time.
// 可以考虑写在配置文件中
mongod --setParameter "transactionLifetimeLimitSeconds=30"

第一次尝试

因为忘记设置后向兼容性,执行失败,在同一个shell中进行设置后,再次插入,提示事务不存在

[10.240.129.36:[email protected]]> Session.startTransactions()
2018-06-30T14:17:10.670+0800 E QUERY    [js] ReferenceError: Session is not defined :
@(shell):1:1
[10.240.129.36:[email protected]]> db.getMongo()
connection to 127.0.0.1:30001
[10.240.129.36:[email protected]]> db.getMongo().startSession()
session { "id" : UUID("887f4564-4f8a-4783-886d-a55a536f41aa") }
[10.240.129.36:[email protected]]> session=db.getMongo().startSession()
session { "id" : UUID("9b3e10b9-93cd-4010-b1a3-0e7b49796db3") }
[10.240.129.36:[email protected]]> session.startTransaction()
[10.240.129.36:[email protected]]> coll_1=session.getDatabase(‘dba‘).coll_1;
dba.coll_1
[10.240.129.36:[email protected]]> coll_2=session.getDatabase(‘dba‘).coll_2;
dba.coll_2
[10.240.129.36:[email protected]]> coll_1.insertOne({‘not_test‘:false})
// 后向兼容性要求为4,也就是说想开启事务必须是mongod4以上的版本
2018-06-30T14:28:55.708+0800 E QUERY    [js] WriteCommandError: Transactions are only supported in featureCompatibilityVersion 4.0. See http://dochub.mongodb.org/core/4.0-feature-compatibility for more information. :
WriteCommandError({
    "ok" : 0,
    "errmsg" : "Transactions are only supported in featureCompatibilityVersion 4.0. See http://dochub.mongodb.org/core/4.0-feature-compatibility for more information.",
    "code" : 50773,
    "codeName" : "Location50773"
})
[email protected]/mongo/shell/bulk_api.js:420:48
Bulk/[email protected]/mongo/shell/bulk_api.js:902:1
Bulk/[email protected]/mongo/shell/bulk_api.js:1150:21
[email protected]/mongo/shell/crud_api.js:252:9
@(shell):1:1
[10.240.129.36:[email protected]]> db.adminCommand({setFeatureCompatibilityVersion:‘4.0‘})
{ "ok" : 1 }

// 可以看到,报错,重新设置版本兼容性后,原先的事务出现了问题
[10.240.129.36:[email protected]]> coll_1.insertOne({‘not_test‘:false})
2018-06-30T14:31:16.706+0800 E QUERY    [js] WriteCommandError: Given transaction number 0 does not match any in-progress transactions. :
WriteCommandError({
    "errorLabels" : [
        "TransientTransactionError"
    ],
    "ok" : 0,
    "errmsg" : "Given transaction number 0 does not match any in-progress transactions.",
    "code" : 251,
    "codeName" : "NoSuchTransaction"
})
[email protected]/mongo/shell/bulk_api.js:420:48
Bulk/[email protected]/mongo/shell/bulk_api.js:902:1
Bulk/[email protected]/mongo/shell/bulk_api.js:1150:21
DBColl[email protected]/mongo/shell/crud_api.js:252:9
@(shell):1:1

// 事务怎么也调不好了

[10.240.129.36:[email protected]]> session.startTransaction()
2018-06-30T14:33:53.293+0800 E QUERY    [js] Error: Transaction already in progress on this session. :
[email protected]/mongo/shell/session.js:732:1
[email protected]/mongo/shell/session.js:925:17
@(shell):1:1
[10.240.129.36:[email protected]]> db.getMongo().abortTransaction
[10.240.129.36:[email protected]]> db.getMongo().abortTransaction
[10.240.129.36:[email protected]]> db.getMongo().abortTransaction
[10.240.129.36:[email protected]]> db.getMongo().abortTransaction
[10.240.129.36:[email protected]]> db.getMongo().abortTransaction
[10.240.129.36:[email protected]]>
[10.240.129.36:[email protected]]> db.getMongo().abortTransaction
[10.240.129.36:[email protected]]> db.getMongo().abortTransaction
[10.240.129.36:[email protected]]> exit
// 直接退出当前连接

第二次尝试:

[10.240.129.36:[email protected]]> session=db.getMongo().startSession()
session { "id" : UUID("b82d71b0-b698-4909-b5b8-a7845dba98b2") }
[10.240.129.36:[email protected]]>  session.startTransaction()
[10.240.129.36:[email protected]]> coll_1=session.getDatabase(‘dba‘).coll_1
dba.coll_1
[10.240.129.36:[email protected]]> coll_2=session.getDatabase(‘dba‘).coll_2;
dba.coll_2
[10.240.129.36:[email protected]]> coll_1.insertOne({‘not_test‘:false})
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5b37270429c5c0c486b4b17b")
}
[10.240.129.36:[email protected]]> coll_2.insertOne({‘not_test‘:false})

// 这里的事务回滚可能是因为超时引起的,默认事务生命周期最大值为1分钟

2018-06-30T15:00:50.629+0800 E QUERY    [js] WriteCommandError: Transaction 0 has been aborted. :
WriteCommandError({
    "errorLabels" : [
        "TransientTransactionError"
    ],
    "ok" : 0,
    "errmsg" : "Transaction 0 has been aborted.",
    "code" : 251,
    "codeName" : "NoSuchTransaction"
})
[email protected]/mongo/shell/bulk_api.js:420:48
Bulk/[email protected]/mongo/shell/bulk_api.js:902:1
Bulk/[email protected]/mongo/shell/bulk_api.js:1150:21
[email protected]/mongo/shell/crud_api.js:252:9
@(shell):1:1
[10.240.129.36:[email protected]]> coll_2.insertOne({‘not_test‘:false})
2018-06-30T15:00:59.308+0800 E QUERY    [js] WriteCommandError: Transaction 0 has been aborted. :
WriteCommandError({
    "errorLabels" : [
        "TransientTransactionError"
    ],
    "ok" : 0,
    "errmsg" : "Transaction 0 has been aborted.",
    "code" : 251,
    "codeName" : "NoSuchTransaction"
})
[email protected]/mongo/shell/bulk_api.js:420:48
Bulk/[email protected]/mongo/shell/bulk_api.js:902:1
Bulk/[email protected]/mongo/shell/bulk_api.js:1150:21
[email protected]/mongo/shell/crud_api.js:252:9
@(shell):1:1

// 事务超时回滚之后,应该还可以重开新的事务才对,这里老是报错

[10.240.129.36:[email protected]]> session.startTransaction()
2018-06-30T15:01:04.932+0800 E QUERY    [js] Error: Transaction already in progress on this session. :
[email protected]/mongo/shell/session.js:732:1
[email protected]/mongo/shell/session.js:925:17
@(shell):1:1

// 内部已经回滚掉了,结果竟然需要我手动回滚才行,晕

[10.240.129.36:[email protected]]> session.abortTransaction()
[10.240.129.36:[email protected]]> session.startTransaction()
[10.240.129.36:[email protected]]> coll_1.insertOne({‘not_test‘:false})
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5b372ac229c5c0c486b4b17e")
}
[10.240.129.36:[email protected]]> coll_2.insertOne({‘not_test‘:false})
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5b372ac529c5c0c486b4b17f")
}

// 试试能不能进行explain操作

[10.240.129.36:[email protected]]> coll_1.explain().find({‘test_explain‘:1})
2018-06-30T15:03:09.375+0800 E QUERY    [js] Error: explain failed: {
    "ok" : 0,
    "errmsg" : "Cannot run ‘explain‘ in a multi-document transaction.",
    "code" : 50767,
    "codeName" : "Location50767"
} :  // 果然是报错了呢,在事务中不能进行explain操作
[email protected]/mongo/shell/utils.js:25:13
[email protected]/mongo/shell/explainable.js:31:1
constructor/[email protected]/mongo/shell/explain_query.js:171:24
constructor/[email protected]/mongo/shell/explain_query.js:210:26
[email protected]/mongo/shell/utils.js:594:1
@(shell2):1:1

// 尝试提交时报错
[10.240.129.36:[email protected]]> session.commitTransaction()
2018-06-30T15:04:21.985+0800 E QUERY    [js] Error: command failed: {
    "errorLabels" : [
        "TransientTransactionError"
    ],
    "ok" : 0,
    "errmsg" : "Transaction 1 has been aborted.",
    "code" : 251,
    "codeName" : "NoSuchTransaction"
} :
[email protected]/mongo/shell/utils.js:25:13
[email protected]/mongo/shell/assert.js:18:14
[email protected]/mongo/shell/assert.js:534:17
[email protected]/mongo/shell/assert.js:618:16
[email protected]/mongo/shell/session.js:929:17
@(shell):1:1

[10.240.129.36:[email protected]]> db.coll_1.find()
{ "_id" : ObjectId("5b371e120d6160b73a9fcee6"), "test" : true }
{ "_id" : ObjectId("5b371e6d0d6160b73a9fcee7"), "test" : true }
[10.240.129.36:[email protected]]> db.coll_2.find()
// 这边可以看到,插入语句并没有真正被执行

[10.240.129.36:[email protected]]> session.commitTransaction()
2018-06-30T15:05:46.288+0800 E QUERY    [js] Error: command failed: {
    "errorLabels" : [
        "TransientTransactionError"
    ],
    "ok" : 0,
    "errmsg" : "Transaction 1 has been aborted.",
    "code" : 251,
    "codeName" : "NoSuchTransaction"
} :
[email protected]/mongo/shell/utils.js:25:13
[email protected]/mongo/shell/assert.js:18:14
[email protected]/mongo/shell/assert.js:534:17
[email protected]/mongo/shell/assert.js:618:16
[email protected]/mongo/shell/session.js:929:17
@(shell):1:1

// 这儿又抽风了,内部回滚之后禁止提交操作,尝试进行回滚,结果说已经提交了,不能回滚,真是晕死

[10.240.129.36:[email protected]]> session.abortTransaction()
2018-06-30T15:06:04.162+0800 E QUERY    [js] Error: Cannot call abortTransaction after calling commitTransaction. :
[email protected]/mongo/shell/session.js:764:1
[email protected]/mongo/shell/session.js:934:17
@(shell):1:1

第三次尝试(成功提交):

[10.240.129.36:[email protected]]> session=db.getMongo().startSession()
session { "id" : UUID("e7935985-160d-4969-adfe-3bae401e155f") }
[10.240.129.36:[email protected]]> session.startTransaction()
[10.240.129.36:[email protected]]> coll_1=session.getDatabase(‘dba‘).coll_1
dba.coll_1
[10.240.129.36:[email protected]]> coll_2=session.getDatabase(‘dba‘).coll_2;
dba.coll_2
[10.240.129.36:[email protected]]> coll_1.insertOne({‘not_test‘:false})
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5b373202d0b208b7386e9c20")
}
[10.240.129.36:[email protected]]> coll_2.insertOne({‘not_test‘:false})
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5b373202d0b208b7386e9c21")
}
[10.240.129.36:[email protected]]> session.commitTransaction()
[10.240.129.36:[email protected]]> use dba
switched to db dba
[10.240.129.36:[email protected]]> db.coll_1.find()
{ "_id" : ObjectId("5b371e120d6160b73a9fcee6"), "test" : true }
{ "_id" : ObjectId("5b371e6d0d6160b73a9fcee7"), "test" : true }
{ "_id" : ObjectId("5b373202d0b208b7386e9c20"), "not_test" : false }
[10.240.129.36:[email protected]]> db.coll_2.find()
{ "_id" : ObjectId("5b373202d0b208b7386e9c21"), "not_test" : false }

第四次尝试(测试回滚):

[10.240.129.36:[email protected]]> session=db.getMongo().startSession()
session { "id" : UUID("e7935985-160d-4969-adfe-3bae401e155f") }
[10.240.129.36:[email protected]]> session.startTransaction()
[10.240.129.36:[email protected]]> coll_1=session.getDatabase(‘dba‘).coll_1
dba.coll_1
[10.240.129.36:[email protected]]> coll_2=session.getDatabase(‘dba‘).coll_2;
dba.coll_2
[10.240.129.36:[email protected]]> coll_1.insertOne({‘not_test‘:false})
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5b373202d0b208b7386e9c20")
}
[10.240.129.36:[email protected]]> coll_2.insertOne({‘not_test‘:false})
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5b373202d0b208b7386e9c21")
}
[10.240.129.36:[email protected]]> session.commitTransaction()
[10.240.129.36:[email protected]]> use dba
switched to db dba
[10.240.129.36:[email protected]]> db.coll_1.find()
{ "_id" : ObjectId("5b371e120d6160b73a9fcee6"), "test" : true }
{ "_id" : ObjectId("5b371e6d0d6160b73a9fcee7"), "test" : true }
{ "_id" : ObjectId("5b373202d0b208b7386e9c20"), "not_test" : false }
[10.240.129.36:[email protected]]> db.coll_2.find()
{ "_id" : ObjectId("5b373202d0b208b7386e9c21"), "not_test" : false }
[10.240.129.36:[email protected]]> session=db.getMongo().startSession()
session { "id" : UUID("cc0e2d23-1766-4ea5-87a5-957efcae28ad") }
[10.240.129.36:[email protected]]> session.startTransaction()
[10.240.129.36:[email protected]]> coll_1=session.getDatabase(‘dba‘).coll_1
dba.coll_1
[10.240.129.36:[email protected]]> coll_2=session.getDatabase(‘dba‘).coll_2;
dba.coll_2
[10.240.129.36:[email protected]]> coll_1.insertOne({‘not_test‘:false})
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5b3732f0d0b208b7386e9c22")
}
[10.240.129.36:[email protected]]> coll_2.insertOne({‘not_test‘:false})
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5b3732f1d0b208b7386e9c23")
}
[10.240.129.36:[email protected]]> session.abortTransaction()
[10.240.129.36:[email protected]]> db.coll_2.find()
{ "_id" : ObjectId("5b373202d0b208b7386e9c21"), "not_test" : false }
[10.240.129.36:[email protected]]> db.coll_1.find()
{ "_id" : ObjectId("5b371e120d6160b73a9fcee6"), "test" : true }
{ "_id" : ObjectId("5b371e6d0d6160b73a9fcee7"), "test" : true }
{ "_id" : ObjectId("5b373202d0b208b7386e9c20"), "not_test" : false }

注意

默认事务超时时间有点短,1分钟
默认锁等待时间短,5毫秒
事务的操作有些繁琐,不如RDS的 begin commit rollback方便(指SHELL操作)
一个事务的对应的oplog不能超过16M(指BSON格式的文件大小)
显式事务功能的开启对WT缓存提出了新的要求。类似于IBP事务不按时提交,类似undo用于存放快照或者旧版本的东西肯定会占用大量WT的空间。

原文地址:http://blog.51cto.com/l0vesql/2134532

时间: 2024-08-07 11:32:07

【MongoDB】4.0版本事务上手测试的相关文章

lucene3.0+版本中文分词测试+搜索结果+创建索引测试

lucene3.0+版本中文分词测试+搜索结果+创建索引测试 import java.io.File; import java.io.IOException; import java.io.StringReader; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.

mongodb 3.0版本安装

参考官方文档 windows平台安装 直接执行的结果: 1.通过浏览器下载,不用迅雷:https://www.mongodb.org/downloads?_ga=1.146766260.1274531242.1445581450#production 2.基本的配置文件:mongod.cfg -----内容systemLog: destination: file path: c:\data\log\mongod.logstorage: dbPath: c:\data\db 注:启动时,也可以指定

MongoDB 4.0版本

MongoDB 简介 是一款跨平台.面向文档的数据库.可实实现高性能.高可.可用性.并且能轻松扩展.是一个基于分布式文件存储开源数据库系统,在高负载的清苦下添加更多节点. MongoDB 也是一个介于关系型数据库和非关系数据库之间的产品,是非关系型数据数据库当中功能最丰富,最像关系数据库的.MongoDB 特点-安装简单,提供了面向文档存储,模式自由丰富的查询语句和多级索引,复制机制,易于水平扩展,可插入存储引擎.跨平台多语言支持·如ruby.python.Java.c++ PHP c# 等多种

MongoDB 3.0 新特性【转】

本文来自:http://www.open-open.com/lib/view/open1427078982824.html#_label3 更多信息见官网: http://docs.mongodb.org/manual/release-notes/3.0/ 参考文章: 测试:http://www.mongoing.com/archives/862 http://www.mongoing.com/benchmark_3_0 配置:http://www.mongoing.com/config_3_0

MongoDB 4.0 RC 版本强势登陆

摘要: MongoDB 因其灵活的文档模型.可扩展分布式设计广受开发者喜爱,在此基础上,MongoDB 4.0 推出了更强大的功能支持,目前4.0第一个RC版本已经发布,本文将介绍 MongoDB 4.0 核心的一些新特性. MongoDB 因其灵活的文档模型.可扩展分布式设计广受开发者喜爱,在此基础上,MongoDB 4.0 推出了更强大的功能支持,目前4.0第一个RC版本已经发布,本文将介绍 MongoDB 4.0 核心的一些新特性. 多文档事务(Multi-Document ACID Tr

【转】MongoDB 3.0 正式版本即将发布,强力推荐

MongoDB 今天宣布3.0 正式版本即将发布.这标志着 MongoDB 数据库进入了一个全新的发展阶段,提供强大.灵活而且易于管理的数据库管理系统. MongoDB 3.0 在性能和伸缩性方面都有非常巨大的提升,通过在存储层的大幅改进实现.内建 WiredTiger 存储引擎,这是一项难以置信的技术实现,提供无门闩.非堵塞算法来利用先进的硬件平台(如大容量芯片缓存和线程化架构)来提升性能.通过 WiredTiger ,MongoDB 3.0 实现了文档级别的并发控制,因此大幅提升了大并发下的

R︱Rstudio 1.0版本尝鲜(R notebook、下载链接、sparkR、代码时间测试profile)

2016年11月1日,RStudio 1.0版本正式发布!这是自2011年2月RStudio发布以来的第10个主要版本,也是更新最大的一次.主要亮点如下: 1.R Notebooks 的辅助工具(实时反馈结果,这个RMD做不来) 2.对sparklyr包的集成支持(R与Spark连接) 3.profvis包进行性能分析(代码运行步骤.代码运行时间) 4.基于readr/readxl/haven,优化数据读取(任意修改载入行名.列名以及一些字符串处理) 5.R Markdown的辅助工具(webs

MongoDB V3 & V2 版本锁性能对比测试及锁的基本概况

1.mongo锁概况: 各版本锁的特性: 当前版本 生产版本最高是 2.6.7[Production Release (2.6.7)] 开发版本是 3.0.0-rc7[Development Releases (unstable)3.0.0] Version < 2.2 : 只支持进程级锁,一个Mongod实例一个锁. 2.8 >Version >= 2.2 : 支持库级锁,一个db一把锁. 目前3.0.0 支持 collection 级别的锁. ps:Mysql的innoDB和Orac

Mongodb 3.0 创建用户

MongoDB 3.0 安全权限访问控制,在添加用户上面3.0版本和之前的版本有很大的区别,这里就说明下3.0的添加用户的方法. 创建第一个用户(该用户需要有grant权限,即:账号管理的授权权限) 1.以非auth认证方式启动数据库: [[email protected] ~]$ mongod --dbpath=/mongodb/data --logpath=/mongodb/log/trace.log --logappend --port=27017 --fork [[email prote