我知道这里也有类似的问题,但如果我需要事务处理,它们要么是telling me以切换回常规RDBMS系统,要么是使用atomic operationstwo-phase commit.第二种解决方案似乎是最佳 Select .第三个我不想遵循,因为似乎很多事情都可能出错,我无法在每个方面进行测试.我很难重构我的项目来执行原子操作.我不知道这是出于我有限的观点(我到目前为止只使用SQL数据库),还是实际上无法做到.

我们想在我们公司试点MongoDB.我们 Select 了一个相对简单的项目——短信网关.它允许我们的软件向蜂窝网络发送SMS消息,而网关则完成了肮脏的工作:通过不同的通信协议与Provider 进行实际通信.网关还管理消息的计费.每个申请这项服务的顾客都必须购买一些信用卡.发送消息时,系统会自动减少用户的余额,如果余额不足,系统会拒绝访问.此外,由于我们是第三方短信Provider 的客户,我们也可能与他们有自己的余额.我们也必须追踪这些.

我开始思考,如果我降低了一些复杂性(外部计费、排队发送短信),如何用MongoDB存储所需的数据.来自SQL世界,我将为用户创建一个单独的表,另一个用于SMS消息,另一个用于存储有关用户余额的事务.假设我为MongoDB中的所有人创建了单独的集合.

想象一下,在这个简化的系统中,短信发送任务包含以下步骤:

  1. 判断用户是否有足够的余额;如果信用不足,拒绝访问

  2. 发送消息并将其存储在SMS集合中,包括详细信息和成本(在实时系统中,消息将具有status属性,任务将接收消息进行传递,并根据其当前状态设置SMS的价格)

  3. 通过发送消息的成本减少用户的余额

  4. 在事务集合中记录事务

这有什么问题吗?MongoDB只能对一个文档进行原子更新.在前面的流程中,可能会发生某种错误,消息被存储在数据库中,但用户余额未更新和/或交易未被记录.

我想出了两个主意:

  • 为用户创建单个集合,并将余额存储为字段,将与用户相关的事务和消息存储为用户文档中的子文档.因为我们可以原子地更新文档,这实际上解决了事务问题.缺点:如果用户发送很多短信,文档的大小可能会变大,并且可能会达到4MB的文档限制.也许我可以在这种情况下创建历史文档,但我认为这不是一个好主意.此外,我不知道如果我把越来越多的数据推送到同一个大文档中,系统会有多快.

  • 为用户创建一个集合,为事务创建一个集合.可以有两种交易:credit purchase种为正余额变化,messages sent种为负余额变化.交易可能有子文档;例如,在messages sent中,SMS的详细信息可以嵌入到事务中.缺点:我不存储当前用户余额,所以每次用户试图发送消息时,我都必须计算它,以判断消息是否可以通过.随着存储事务数量的增加,这种计算可能会变得缓慢.

我对 Select 哪种方法有点困惑.还有其他解决方案吗?我在网上找不到任何关于如何解决此类问题的最佳实践.我猜许多试图熟悉NoSQL世界的程序员在一开始也面临着类似的问题.

推荐答案

从4.0开始,MongoDB将拥有多文档ACID事务.计划是首先启用副本集中的部署,然后启用分片集群.MongoDB中的事务感觉就像开发人员熟悉的关系数据库中的事务一样——它们是多语句的,具有相似的语义和语法(比如start_transactioncommit_transaction).重要的是,对MongoDB进行的允许事务的更改不会影响不需要事务的工作负载的性能.

更多详情请参见here.

拥有分布式事务并不意味着应该像在表格关系数据库中那样对数据进行建模.接受文档模型的强大功能,遵循数据建模的好方法和推荐的practices种方法.

Mongodb相关问答推荐

MongoDB:用特殊字符创建的drop collection

MongoDB-如何过滤和获取数组字段中的最新数据

从 MongoDB 中的聚合结果中获取不同的值

MongoDB:通过嵌套数组中的最后一个元素值获取文档

有没有办法从另一条记录中插入一条记录

如何将 json 字符串编组到 bson 文档以写入 MongoDB?

Meteor 方法与deny/allow 规则

MongoDB:按标签获取文档

获取收集字节使用情况统计信息的pymongo方法?

mongodb - 查找具有最接近整数值的文档

如何在 MongoDB 中进行内部连接?

如何返回 MongoDB 中文档的 ObjectId 或 _id?和错误$in 需要一个数组

如何使用 angular.js 推送通知?

如何使用 MongoDB 以编程方式预拆分基于 GUID 的分片键

如何在 MongoDB Map-reduce 映射函数中使用变量

Mongodb 设计,嵌入与关系

缩短 MongoDB 属性名称值得吗?

我可以使用字符串作为 mongodb 文档的 ID 类型吗?

mongoose查询返回 null

哪个数据库适合我的应用程序 mysql 或 mongodb ?使用 Node.js 、 Backbone 、 Now.js