MongoDB 事务
优质博文:IT-BLOG-CN
一直以来,不支持事务是MongoDB
一直被诟病的问题,当然也可以说这是NoSQL
数据库的一种权衡(放弃事务,追求高性能、高可扩展)
但实质上,MongoDB
很早就有事务的概念,但是这个事务只能是针对单文档的,即单个文档的操作是有原子性保证的。
在4.0
版本之后,MongoDB
开始支持多文档的事务:
4.0
版本支持副本集范围的多文档事务。
4.2
版本支持跨分片的多文档事务(基于两阶段提交)。
在事务的隔离性上,MongoDB
支持快照snapshot
的隔离级别,可以避免脏读、不可重复读和幻读。
尽管有了真正意义上的事务功能,但多文档事务对于性能有一定的影响,应用应该在充分评估后再做选用。
一致性
一致性是一个复杂的话题,而一致性更多从应用角度上提出的,比如:
向系统写入一条数据,应该能够马上读到写入的这个数据。
在分布式架构的CAP
理论以及许多延续的观点中提到,由于网络分区的存在,要求系统在一致性和可用性之间做出选择,而不能两者兼得。
在MongoDB
中,这个选择是可以由开发者来定的。MongoDB
允许客户端为其操作设定一定的级别或者偏好,包括:
【1】read preference
:读取偏好,可指定读主节点、读备节点,或者是优先读主、优先读备、取最近的节点;
【2】write concern
写关注,指定写入结果达到什么状态时才返回,可以为无应答(none)、应答(ack),或者是大多数节点完成了数据复制等等;
【3】read concern
读关注,指定读取的数据版本处于怎样的状态,可以为读本地、读大多数节点写入,或者是线性读linearizable
等等;
使用不同的设定将会产生对于C
(一致性)、A
(可用性)的不同的抉择,比如:
【1】将读偏好设置为primary
,此时读写都在主节点上。 这保证了数据的一致性,但一旦主节点宕机会导致失败(可用性降低)
【2】将读偏好设置为secondaryPrefered
,此时写主,优先读备,可用性提高了,但数据存在延迟(出现不一致)
【3】将读写关注都设置为majority
(大多数),一致性提升了,但可用性也同时降低了(节点失效会导致大多数写失败)
关于这种权衡的讨论会一直存在,而MongoDB
除了提供多样化的选择之外,其主要是通过复制、基于心跳的自动failover
等机制来降低系统发生故障时产生的影响,从而提升整体的可用性。