MongoDB 基础系列十六:增删查改 CRUD Concepts 之原子性和事务

前言

此篇博文是 Mongdb 基础系列之一;

本文为作者的原创作品,转载需注明出处;

简介

In MongoDB, a write operation is atomic on the level of a single document, even if the operation modifies multiple embedded documents within a single document.

甚至当多个 write 操作作用到多个不同的嵌入式文档中也是一样,事务原子性是作用在单个 document 上的;

When a single write operation modifies multiple documents, the modification of each document is atomic, but the operation as a whole is not atomic and other operations may interleave. However, you can isolate a single write operation that affects multiple documents using the $isolated operator.

当一个写入操作要修改多个文档的时候,单个文档的写入操作是原子的,但是整个写入操作不是原子性的,其它的写入操作会干涉当前写入操作的事务完整性;但是,你可以通过使用$isolated()操作符对一个写入操作进行事务隔离;备注,这里隔离指的是,其它操作不会干涉到当前操作;

$isolated 操作符

使用 [$isolated] 操作符,当一个会作用到多个 documents 之上的写入操作开始对第一个文档进行写入以后,其它操作便不能对该写入操作进行干涉了;原因是,一旦开始写入,它可以保证任何客户端在写入过程中,相关文档对客户端是不可见的;

$isolated does not work with sharded clusters.

An isolated write operation does not provide “all-or-nothing” atomicity. That is, an error during the write operation does not roll back all its changes that preceded the error.

注意了,一个 isolated 写入操作并不提供要么全部写入要么什么都不写入的原子事务性功能;也就是说,一旦在写入过程中,某个文档写入出错,并不会保证之前写入的 documents 能够 rollback;这也就决定了,MongoDB 不适合用于事务性要求非常高的场景,比如金融交易等等;

注意,

之所以使用 $isolated 操作符能够保证当前的写入操作不被其它操作所干涉,是因为它在 collection 上添加了排他锁;

For an example of an update operation that uses the $isolated operator, see $isolated. For an example of a remove operation that uses the $isolated operator, see Isolate Remove Operations.

Transaction-Like Semantics

Since a single document can contain multiple embedded documents, single-document atomicity is sufficient for many practical use cases. For cases where a sequence of write operations must operate as if in a single transaction, you can implement a two-phase commit in your application.

虽然,单个文档的原子性能够满足绝大部分的场景;但是,有时候,我们的确需要对一系列相关的写入操作在一个事务中执行,那么这个时候,你可以考虑在你的应用中实现 two-phase commit

However, two-phase commits can only offer transaction-like semantics. Using two-phase commit ensures data consistency, but it is possible for applications to return intermediate data during the two-phase commit or rollback.

For more information on two-phase commit and rollback, see Perform Two Phase Commits.

Concurrency Control

Concurrency control allows multiple applications to run concurrently without causing data inconsistency or conflicts.

并行控制允许多个应用同时执行并且保证数据的一致性;

One approach is to create a unique index on a field that can only have unique values. This prevents insertions or updates from creating duplicate data. Create a unique index on multiple fields to force uniqueness on that combination of field values. For examples of use cases, see update() and Unique Index and findAndModify() and Unique Index.

使用 unique index 可以保证同步的插入或更新操作不会创建重复的数据;为什么呢?这里主要是针对多个字段组成一个复合字段索引的情况,因此可以通过复合字段索引判断数据是否有重复;

Another approach is to specify the expected current value of a field in the query predicate for the write operations. The two-phase commit pattern provides a variation where the query predicate includes the application identifier as well as the expected state of the data in the write operation.