MongoDB在我们的生产环境中已经大规模的使用,它的性能与稳定已经得到的充分的验证,稳定在线的时间已经有一年多了。在这个过程中的确给我们带来了很多性能上的优势,虽然它不像关系型数据那样有方便的join查询,但就目前我们的应用场景这些缺点(暂且把它当做缺点吧)都是可以接受的。最近在思考了下nosql数据库并发控制方面的问题,在此记录一下。
数据库的并发控制机制不外乎就两种情况:
1.悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。
2.乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性,乐观锁不能解决脏读和多读的问题。
悲观锁假定其他用户企图访问或者改变你正在访问、更改的对象的概率是很高的,因此在悲观锁的环境中,在你开始改变此对象之前就将该对象锁住,并且直到你提交了所作的更改之后才释放锁。悲观的缺陷是不论是页锁还是行锁,加锁的时间可能会很长,这样可能会长时间的限制其他用户的访问,也就是说悲观锁的并发访问性不好。
乐观锁则认为其他用户企图改变你正在更改的对象的概率是很小的,因此乐观锁直到你准备提交所作的更改时才将对象锁住,当你读取以及改变该对象时并不加锁。可见乐观锁加锁的时间要比悲观锁短,乐观锁可以用较大的锁粒度获得较好的并发访问性能。但是如果第二个用户恰好在第一个用户提交更改之前读取了该对象,那么当他完成了自己的更改进行提交时,数据库就会发现该对象已经变化了,这样,第二个用户不得不重新读取该对象并作出更改。这说明在乐观锁环境中,会增加并发用户读取对象的次数。
MongoDB不支持事务,也就没有数据库级别的悲观锁了。那么我们的并发控制只能依赖乐观锁,乐观锁非常适合我的应用场景,并且性能更高。刚才说的是数据库级别的并发控制,当然如果说到程序级别并发控制机制,同样是悲观锁和乐观锁。我们的经常用的lock就是一种悲观锁,不论是java还是.net。那乐观锁呢?当然这个就是软件事务内存,Clojure和Scala言语的内存管理,它们天生就是支持并发编程的。
如果要在普通的关系型数据库里实现乐观并发控制,我们一般需要为其加上一个额外的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查询,如果它返回updatedExisting为true,则表示更新成功了。当然如果使用java驱动的话,可以使用dbCollection.update和dbCollection.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并发控制乐观锁的实现方式。
分享到:
相关推荐
MongoDB是一种流行的开源、分布式、文档型的NoSQL数据库,其设计目标是处理大量数据的同时,提供高可用性、高性能和可伸缩性。在这个"MongoDB源码和PPT"的压缩包中,我们可以期待深入理解MongoDB的核心概念、工作...
Nosql数据库在分布式数据库中的应用非常广泛,特别是mongodb数据库。mongodb数据库是当前最流行的非关系型数据库,已经被广泛应用于实际项目中。 4. 分布式数据库的优点 分布式数据库的优点包括降低了数据传送...
根据提供的信息,我们可以推断出该文档主要围绕“NoSQL数据库入门”这一主题展开,并且它是一本高清PDF格式的学习指导书籍。尽管文档的部分内容似乎与Linux公社网站介绍有关,但我们的重点将放在提取与NoSQL数据库...
- **横向扩展性**:NoSQL数据库通常易于扩展,可以通过增加硬件节点实现水平扩展,以应对高并发和大数据量的场景。 - **灵活性**:NoSQL数据库支持动态模式,无需预定义数据结构,适应快速变化的需求。 - **高...
NoSQL数据库的设计初衷是为了处理大规模数据集、高并发访问及提供灵活的数据模型支持。NoSQL这一概念的提出主要是为了应对传统关系型数据库在Web 2.0时代所遇到的一些挑战。 #### 二、NoSQL数据库的产生背景 随着...
NoSQL数据库是一种非关系型的数据库,旨在解决传统关系数据库在应付Web 2.0网站,特别是超大规模和高并发的SNS类型的Web 2.0网站中的问题。NoSQL数据库的优点是可以处理超大量的数据,可以运行在便宜的PC服务器集群...
文档型NoSQL数据库的代表是MongoDB,它以文档作为数据的基本存储单位,每个文档都是一组数据项的集合。MongoDB具有灵活的文档模型、高性能和高可用性的特点,特别适合用于大数据处理和实时Web应用。 综上所述,...
NoSQL数据库的兴起是由于关系数据库无法满足Web2.0的需求,主要表现在海量数据的管理需求、数据高并发的需求和高可扩展性和高可用性的需求等方面。 5.2 NoSQL兴起的原因 关系数据库已经无法满足Web2.0的需求,主要...
NoSQL数据库通常采用分布式架构,适用于大数据量和高并发的场景。 【SQL数据库详解】 1. **Oracle**:作为一款历史悠久的商业数据库,Oracle提供了强大的功能,如Virtual Private Database、Data Guard和Automatic...
它使用MVCC(多版本并发控制)机制,确保写操作不阻塞读操作,同时提供了数据版本管理。Cassandra的视图功能基于映射/减少模型,支持服务器端文档验证和实时更新,适用于数据变化较少,需要预定义查询和统计的应用,...
在大数据、实时分析和高并发场景下,NoSQL 数据库如 MongoDB 通常表现出色。 "NoSQL Manager for MongoDB" 是一款专为 MongoDB 设计的管理工具,它提供了直观的图形用户界面(GUI),使用户能够更轻松地管理 ...
NoSQL数据库,全称为"Not Only SQL",是一种非关系型的数据库系统,旨在解决传统关系型数据库在处理大规模数据和高并发场景下遇到的问题。在90年代,由于网站访问量较小,静态网页为主,单一数据库可以满足需求。但...
* 高性能:云数据库MongoDB版提供了高性能的NoSQL数据库解决方案,满足大数据量和高并发请求的应用场景。 * 可靠性高:云数据库MongoDB版具备高可用性和自动故障转移功能,确保数据的安全性和可靠性。 * 可扩展性强...
* 并发优化:云数据库MongoDB版提供了并发优化机制,能够提高并发性能。 七、故障处理 云数据库MongoDB版提供了多种故障处理机制,旨在提高数据库的可用性,包括: * 故障检测:云数据库MongoDB版提供了故障检测...
1. **互联网公司的应用场景**:许多互联网公司如支付宝采用了NoSQL数据库来处理高并发、大数据量的情况,如用户行为分析、推荐系统等。 2. **数据架构启示**:通过对比互联网公司与传统行业的数据架构,可以发现前者...
总的来说,NoSQL数据库是为了解决传统关系型数据库在处理大规模、高并发数据时的局限性而产生的。它提供了新的解决方案,如分布式存储、非ACID特性的数据模型和内存缓存,以适应互联网时代的需求。随着技术的发展,...
### NoSQL分布式数据库知识点解析 #### 一、选择题知识点详解 **1. 关系数据库与非关系数据库** - **关系数据库**: MySQL、SQL Server 和 Oracle 均属于关系数据库,它们采用 SQL 作为标准查询语言,支持 ACID ...
NoSQL数据库如Memcached、MongoDB、Cassandra、HBase等在内存分配、缓存策略、数据冗余、API设计等方面各有特点,适用于不同的应用场景。例如,Memcached适合快速的键值存储,而HBase是基于Hadoop的大数据存储系统,...