Mat*_*agé 29 repository-pattern mongodb
我知道我无法锁定单个mongodb文档,实际上也无法锁定集合.
但是,我有这种情况,我认为我需要一些方法来防止多个线程(或进程,这并不重要)修改文档.这是我的情景.
我有一个包含类型A的对象的集合.我有一些代码检索类型A的文档,在数组中添加元素作为document(a.arr.add(new Thing())的属性,然后将文档保存回mongodb.这段代码是并行的,我的应用程序中的多个线程可以执行这些操作,现在没有办法阻止线程在同一文档上并行执行这些操作.这很糟糕,因为其中一个线程可能会覆盖另一个线程的工作.
我确实使用存储库模式来抽象对mongodb集合的访问,所以我只处理我的处理中的CRUD操作.
现在我考虑一下,也许这是对存储库模式的限制,而不是mongodb的限制导致我的麻烦.无论如何,我怎样才能使这段代码"线程安全"?我想这个问题有一个众所周知的解决方案,但是对mongodb和存储库模式不熟悉,我不会马上看到它.
谢谢
小智 14
嘿,我现在认为唯一的方法是添加一个状态参数并使用操作findAndModify(),这使您能够原子地修改文档.它有点慢,但应该做的伎俩.
因此,假设您添加了一个状态attribut,当您检索文档时,将状态从"IDLE"更改为"PROCESSING".然后,您更新文档并将其保存回集合,再次将状态更新为"IDLE".
代码示例:
var doc = db.runCommand({
"findAndModify" : "COLLECTION_NAME",
"query" : {"_id": "ID_DOCUMENT", "status" : "IDLE"},
"update" : {"$set" : {"status" : "RUNNING"} }
}).value
Run Code Online (Sandbox Code Playgroud)
将COLLECTION_NAME和ID_DOCUMENT更改为正确的值.默认情况下,findAndModify()返回旧值,这意味着客户端的状态值仍然是IDLE.因此,当您完成更新后,只需再次保存/更新所有内容.
您需要注意的唯一想法是您一次只能修改一个文档.
希望能帮助到你.
在进行mongodb升级时偶然发现了这个问题.与此问题不同,现在mongodb支持开箱即用的文档级锁定.
来自:http://docs.mongodb.org/manual/faq/concurrency/
"MongoDB中的锁是多么精细?
在3.0版中更改.
从版本3.0开始,MongoDB附带了WiredTiger存储引擎,该引擎对大多数读写操作使用乐观并发控制.WiredTiger仅在全局,数据库和集合级别使用意图锁.当存储引擎检测到两个操作之间的冲突时,会发生写入冲突,导致MongoDB透明地重试该操作."
"医生,这很伤我这样做时,这个 "
"那就不要那样做了!"
基本上,你所描述的内容听起来就像你有一个串行依赖 - MongoDB或其他什么,你的算法有一个点,操作必须序列化.这将是一个固有的瓶颈,如果你绝对必须这样做,你将不得不安排某种信号量来保护它.
所以,要看的地方是你的算法.你能消除吗?例如,您是否可以通过某种冲突解决方案处理它,例如"将记录记录到本地'更新;存储记录",以便在存储之后新记录将是获得该密钥的记录?
| 归档时间: |
|
| 查看次数: |
23928 次 |
| 最近记录: |