`
城的灯
  • 浏览: 150046 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

nosql数据库(MongoDB)并发控制

    博客分类:
  • 2012
 
阅读更多

MongoDB在我们的生产环境中已经大规模的使用,它的性能与稳定已经得到的充分的验证,稳定在线的时间已经有一年多了。在这个过程中的确给我们带来了很多性能上的优势,虽然它不像关系型数据那样有方便的join查询,但就目前我们的应用场景这些缺点(暂且把它当做缺点吧)都是可以接受的。最近在思考了下nosql数据库并发控制方面的问题,在此记录一下。

 

 

 

数据库的并发控制机制不外乎就两种情况:

1.悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。

2.乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性,乐观锁不能解决脏读和多读的问题。

悲观锁假定其他用户企图访问或者改变你正在访问、更改的对象的概率是很高的,因此在悲观锁的环境中,在你开始改变此对象之前就将该对象锁住,并且直到你提交了所作的更改之后才释放锁。悲观的缺陷是不论是页锁还是行锁,加锁的时间可能会很长,这样可能会长时间的限制其他用户的访问,也就是说悲观锁的并发访问性不好。

乐观锁则认为其他用户企图改变你正在更改的对象的概率是很小的,因此乐观锁直到你准备提交所作的更改时才将对象锁住,当你读取以及改变该对象时并不加锁。可见乐观锁加锁的时间要比悲观锁短,乐观锁可以用较大的锁粒度获得较好的并发访问性能。但是如果第二个用户恰好在第一个用户提交更改之前读取了该对象,那么当他完成了自己的更改进行提交时,数据库就会发现该对象已经变化了,这样,第二个用户不得不重新读取该对象并作出更改。这说明在乐观锁环境中,会增加并发用户读取对象的次数。

 

 

MongoDB不支持事务,也就没有数据库级别的悲观锁了。那么我们的并发控制只能依赖乐观锁,乐观锁非常适合我的应用场景,并且性能更高。刚才说的是数据库级别的并发控制,当然如果说到程序级别并发控制机制,同样是悲观锁和乐观锁。我们的经常用的lock就是一种悲观锁,不论是java还是.net。那乐观锁呢?当然这个就是软件事务内存ClojureScala言语的内存管理,它们天生就是支持并发编程的。

 

如果要在普通的关系型数据库里实现乐观并发控制,我们一般需要为其加上一个额外的Version字段,它是整型,也可能是个时间戳。在更新某条记录时,我们将这个字段的旧值作为UPDATE语句的条件之一,同时这个字段也会写入新的值。如果这次更新影响了某条记录,那么表示更新成功,反之则表示这条记录已经被删除,或是在读取提交之间遇到了其他提交操作。在SQL Server中存在一个Timestamp类型,这个类型的字段会在记录修改时自动更新。

要在MongoDB实现乐观锁,方式差不多,只是update完了之后,不会返回修改的数据条数,得还要自己去查询一下是否修改成功。

>db.log.update({"uuid":"1",version:1},{$set:{"enddate":"2012-5-19 17:17:10",version:2}})

> db.$cmd.findOne({getlasterror:1}) {   "updatedExisting" : true,     "n" : 1,        "connectionId" : 1, "err" : null,        "ok" : 1 }

>db.log.update({"uuid":"1",version:1},{$set:{"enddate":"2012-5-19 17:17:10",version:2}})

> db.$cmd.findOne({getlasterror:1}) {   "updatedExisting" : false,     "n" : 0,        "connectionId" : 1, "err" : null,        "ok" : 1 }   

  

update语句后面跟上一句db.$cmd查询,如果它返回updatedExistingtrue,则表示更新成功了。当然如果使用java驱动的话,可以使用dbCollection.updatedbCollection.getStats(),便可以更新并且返回状态信息。但是db.$cmd查询的结果是否准确呢?如果在update语句和db.$cmd查询之间,如果另外一个连接恰好也执行了一次update操作,那么db.$cmd返回的是哪次更新的结果?通过查询官方资料,db.$cmd查询是与连接相关,这便不会有问题了。不过值得注意的是,驱动程序是自动管理连接的,也就是说当update()完成之后getstats()有可能使用的不是同一个链接了,这个时候db.$cmd返回的状态信息就不准确。所以如果采用上诉方式你要确保自己两次获得的是同一个链接。如果你想一直使用同一个连接,可以用下边这种方式:

DB db...;

db.requestStart();

code....

db.requestDone();

但是如果最后db.requestDone()没有被调用,该连接不会被交还给线程池,所以,一定要在finally块中调用db.requestDone()

 

 

由于我使用spring来管理mongo驱动,我不喜欢上面那种保持一个链接的方式,所以我用findAndModify来更新数据,当然更新条件自然同样需要包括版本号。如果更新成功,那么findAndModify命令则会返回更新前的数据,否则则返回空文档。这种使用数据库命令行的方式就可以避免保持同一个链接的要求。该方式也是我推荐的方式,官方文档已经说的很清楚了。

This command can be used to atomically modify a document (at most one) and return it. Note that, by default, the document returned will not include the modifications made on the update.

以上便是mongodb并发控制乐观锁的实现方式。

 

分享到:
评论

相关推荐

    什么是NoSQL数据库?

    关系型数据库和NoSQL数据库 什么是NoSQL 大家有没有听说过“NoSQL”呢?近年,这个词极受关注。看到“NoSQL”这个词,大家可能会误以为是“No!SQL”的缩写,并深感愤怒:“SQL怎么会没有必要了呢?”但实际上,它是...

    mongodb nosql,安装简单

    NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。虽然NoSQL流行语火起来才短短一年的时间,但是不可否认,现在已经开始了第二代运动。尽管早期的堆栈代码只能算是一种...

    MongoDB基础入门到高级进阶

    MongoDB是一个开源、高性能、无模式的文档型数据库,是NoSQL数据库产品中的一种。它的出现主要应对“三高”等问题,它可以解决需要存储数据量大、高并发读写、高可用的现实问题,适用于社交朋友圈、游戏积分、物流...

    二、大数据与分布式.pdf

    Tip:常见的基于⽂档存储的 NoSQL 数据库有:Lotus Notes、CouchDB、MongoDB 和 Riak 等。 2.4 基于图存储的 NoSQL 数据库 传统图数据库⼤部分是⾯向对象的,虽然它们在节点遍历等图数据操作中都具有很好的性能,...

    基于消息中间件及MongoDB的物联网应用服务平台

    本文依托于智能燃气数据管理系统,针对其物联网平台架构中应用服务平台在大规模设备接入场景下的性能瓶颈,提出一种结合消息中间件Kafka与NoSQL数据库MongoDB的混合方案.根据燃气公司和设备厂商的应用背景实现该方案...

    Java开发面试-MongoDB专区

    首先,MongoDB是一个开源的NoSQL数据库,它以文档的形式存储数据,并采用类似JSON的BSON格式。在面试中,面试官可能会问到MongoDB的基本概念和特点,例如文档、集合、数据库、索引等,以及与传统关系型数据库的区别...

    Mongodb基础知识详解(值得珍藏).pdf

    MongoDB是一个流行的NoSQL数据库,它以高性能、可扩展性和灵活性而著称。在开发应用程序时,无论是Web应用程序、移动应用程序还是后端服务,都需要一个高效的数据存储和管理解决方案。 首先,掌握MongoDB基础知识...

    大数据常用数据库汇总.pdf

    3、⽂档数据库:MongoDB、CouchDB、Perservere、Terrastore、RavenDB等,下⾯简单介绍⼏个 (1)MongoDB:开源、⾯向⽂档,也是当下最⼈⽓的NoSQL数据库。 (2)CounchDB:Apache CounchDB是⼀个使⽤JSON的⽂档...

    基于微服务的旅行社门店系统的设计实现.zip

    数据库设计:根据不同的服务需求,可能使用了多种数据库技术,如关系型数据库MySQL、NoSQL数据库MongoDB等,以满足不同场景的数据存储需求。API接口:系统提供了丰富的RESTful API接口,使得第三方应用可以轻松地与...

    超详细mongodb教程.zip

    NoSQL 简介 NoSQL(NoSQL = Not Only SQL )...数据进行挖掘,那SQL数据库已经不适合这些应用了, NoSQL数据库的发展也却能很好的处理这些大的 数据。 实例社会化关系网: Each record: UserID1, UserID2 Separate records

    mysql笔记,mysql优化图解

    NoSql数据库: MongoDB(特点是面向文档) 2NF: 表中的记录是唯一的, 就满足2NF, 通常我们设计一个主键来实现 3NF: 即表中不要有冗余数据, 就是说,表的信息,如果能够被推导出来,就不应该单独的设计一个字段来存放...

    ycsb-mongodb

    可扩展性:YCSB支持多种数据库和存储系统,包括关系型数据库、NoSQL数据库、分布式文件系统等,使得测试可以针对不同的系统进行比较和评估。 客户端压力:YCSB可以模拟大量并发用户并提供各种负载测试模式,可以测试...

    基于C#的游戏服务器后台.zip

    基于C#开发游戏服务器后台涉及多个关键技术和设计...配置关系型数据库(如MySQL、PostgreSQL)或NoSQL数据库(如MongoDB、Cassandra)来持久化游戏数据。使用ADO.NET、EF Core等ORM工具简化数据库交互。 服务间通信:

    基于NoSQL的PDM产品结构数据组织 (2013年)

    SQL的优势,以及PDM中产品结构树的创建理念,结合产品结构树中的结构关系和非关系型数据库MongoDB的特点,探讨PDM中的数据在MongoDB中数据存储结构,打破以往关系型数据库表结构的传统模式,建立一种基于NoSQL的PDM数据...

    程序员面试必看参考话术 万字!

    在这几年的项目开发中,我掌握了并发、微服务、多线程等技术的应用,以及我能够熟练使用Oracle,MySQL等关系型数据库以及现在比较获得NoSQL( MongoDB)非关系型数据库。我还掌握了一些有关于项目中的优化问题,如:...

    QuestionSystem-Rebuild:LR Workshop QuestionSystem重建

    数据库使用NoSQL数据库:MongoDB 使用cluster模块提高多核CPU利用率 使用Nginx做反向代理及静态文件分发(或CDN)以实现高并发及API的URL简洁化 单服务器情况下使用Docker部署服务 后期将加入HTTPS和HTTP2的支持 网页...

    Redis学习手册

    在过去的几年中,NoSQL 数据库一度成为高并发、海量数据存储解决方案的代名词,与之相应的产 品也呈现出雨后春笋般的生机。然而在众多产品中能够脱颖而出的却屈指可数,如 Redis、MongoDB、 BerkeleyDB 和 CouchDB ...

    NoSQL和Redis简介及Redis在Windows下的安装和使用教程

    现有Nosql DB 产品: Redis/MongoDB/Memcached/Hbase/Cassandra/ Tokyo Cabinet/Voldemort/Dynomite/Riak/ CouchDB/Hypertable/Flare/Tin/Lightcloud/ KiokuDB/Scalaris/Kai/ThruDB, 等等~~~ 为什么需要NoSQL非关系...

    MongoDB系列教程(一):NoSQL起源

    为什么出现NoSQL? 随着互联网的发展,当我们把一台服务器一台服务器变成两台服务器,当我们开始建立数据备份,当我们需要加一个缓冲层,来调整所有的查询,投入更多的硬件。 最后,需要将数据切分多个集群上,并...

    大数据采集方法.pdf

    ⼤数据的采集⽅法 1)数据库采集 Redis、MongoDB和HBase等NoSQL数据库常⽤于数据的采集。企业通过在采集端部署⼤量数据库,并在这些数据库之间进⾏负载 均衡和分⽚,来完成⼤数据采集⼯作。 2)系统⽇志采集 系统⽇...

Global site tag (gtag.js) - Google Analytics