我正在研究NoSQL以扩展数据库的替代方案.如果我想要对这些事情敏感的基于事务的事情,我该怎么办?
一般来说,NoSQL解决方案比关系数据库具有更轻量级的事务语义,但在某种程度上仍然具有原子操作的功能.
通常,执行主 - 主复制的那些提供较少的一致性和更高的可用性.因此,应该为正确的问题选择合适的工具.
许多提供单个文档(或行等)级别的事务.例如,对于MongoDB,单个文档存在原子性 - 但文档可能相当丰富,因此通常可以很好地工作 - 这里有更多信息.
这是我发现的最适合任何NoSQL数据库的答案.这是来自Heroku.com的Adam Wiggins的2007年博客文章:
使用数据库事务将货币从一个银行账户转移到另一个银行账户的旧例子是完全牛市.正确的解决方案是存储分类帐事件列表(帐户之间的转移),并将当前余额显示为分类帐的总和.如果您使用函数式语言进行编程(或以这种方式思考),这很明显.
来自:http://adam.heroku.com/past/2007/12/17/a_world_without_sql/(他的网站非常适合可扩展性的想法.)
我将上段解释为:
为成员帐户创建数据库.
创建消息队列.昵称它为"分类帐".
添加后台工作程序以完成队列中的每个请求.
更多信息.在队列/后台工作人员:http://adam.heroku.com/past/2009/4/14/building_a_queuebacked_feed_reader_part_1/
客户(也称为会员或客户)按照以下步骤取钱:
提交取钱的请求.
请求被发送到服务器.
服务器将其放入队列中.消息是:"拿出5,000美元."
显示客户:"请等待请求正在履行......"
客户端计算机每2秒轮询一次服务器,询问"请求是否已满足?"
在服务器上,后台工作人员以先进/先出的方式完成其他成员的先前请求.最终,他们得到了客户要求取钱的请求.
一旦请求得到满足,客户将收到一条带有新余额的消息.
如果您熟悉Node.js或Ruby/Rack,可以使用Heroku.com快速创建一个小模型.
一般的想法似乎相当容易,并且比使用数据库中的事务更好,这使得它难以扩展.
免责声明:我还没有以任何方式实现这一点.我好奇地读了这些东西,尽管我对它们没有实际需要.是的,@ gbn是对的,有交易的RDBMS可能足以满足Timmy和我的需求.尽管如此,通过开源工具和一个名为" Razorblades的龙卷风 " 的操作方法网站,您可以在多大程度上了解NoSQL数据库.
NoSQL涵盖了各种工具和服务,包括键值,文档,图形和宽列存储.他们通常通过分发数据处理来尝试提高数据存储的可伸缩性.事务需要有关DB如何执行用户操作的ACID属性.ACID限制了可扩展性的改进:大多数NoSQL工具放宽了操作的一致性标准,以获得容错和扩展的可用性,这使得实施ACID事务变得非常困难.
分布式数据存储的常见理论推理是CAP定理:不能同时实现一致性,可用性和分区容差.SQL,NoSQL和NewSQL工具可以根据它们放弃的内容进行分类; 这里可以找到一个好身材.
替代ACID的一组新的,更弱的要求是BASE("基本上可用,软状态,最终一致性").但是,最终一致的工具("最终所有对项目的访问将返回最后更新的值")在银行等交易应用程序中难以接受.这里一个好主意是使用内存,面向列和分布式SQL/ACID数据库,例如VoltDB ; 我建议看看这些"NewSQL"解决方案.
只想在这个帖子上评论货币交易建议.交易是你真正想要用于汇款的东西.
给出如何转移的例子是非常好和整洁的.
但在现实生活中,转移资金可能包括费用或支付给其他账户.人们使用来自其他帐户的某些卡获得奖金,或者他们可能从他们的帐户中获得相同系统中的另一个帐户的费用.费用或付款可能因金融交易而有所不同,您可能需要保持簿记系统,以显示每笔交易的信用和借记.
这意味着您希望同时更新多个行,因为一个帐户的信用额度可以在一个或多个帐户上扣款.首先锁定行,以便在更新之前不会发生任何变化,然后确保写入的数据与事务一致.
这就是你真正想要使用交易的原因.如果在写入一行时出现任何问题,您可以回滚整组更新而不会使金融交易数据结束不一致.
一个交易和两个操作(例如一个支付5,000美元,第二个支付5,000美元)的问题是,您有两个具有相同优先级的帐户.您不能使用一个帐户来确认第二个(或以相反的顺序).在这种情况下,您可以保证只有一个帐户是正确的(已确认),第二个(确认)可能已失败.让我们看看为什么它会失败(使用消息aproatch,发送者由接收者确认):
写入+ $ 5,000到接收者帐户
如果成功 - 写入 - $ 5,000到发件人帐户
如果失败 - 请尝试反复或取消或显示消息
保证为#1保证.但是谁保证#2失败了?反向顺序相同.
但是这可以实现在没有事务和NoSQL的情况下是安全的.您始终被允许使用将从发送方和接收方确认的第三方实体,并保证您的操作已执行:
生成唯一的事务ID并创建事务实体
写入+ $ 5,000到接收者帐户(参考交易ID)
如果成功 - 设置要发送的事务状态
写 - $ 48到sedned帐户帐户(参考交易ID)
如果成功 - 设置要接收的交易状态
此交易记录将保证发送/接收按摩是可以的.现在,您可以按交易ID检查每条消息,以及是否已收到或已完成状态 - 您可以考虑用户余额.