Azure Service Fabric 可靠集合中的事务和锁模式Transactions and lock modes in Azure Service Fabric Reliable Collections

事务Transaction

事务是作为单个逻辑工作单元执行的一系列操作。A transaction is a sequence of operations performed as a single logical unit of work. 它表现出数据库事务常见的 ACID(原子性、一致性、隔离性、持续性)属性: It exhibits the common ACID (atomicity, consistency, isolation, durability) properties of database transactions:

  • 原子性:事务必须是原子工作单元。Atomicity: A transaction must be an atomic unit of work. 换而言之,要么执行其所有数据修改,要么一个数据修改也不执行。In other words, either all its data modifications are performed, or none of them is performed.
  • 一致性:事务在完成时,必须使所有的数据都保持一致状态。Consistency: When completed, a transaction must leave all data in a consistent state. 事务结束时,所有内部数据结构必须都正确。All internal data structures must be correct at the end of the transaction.
  • 隔离:由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。Isolation: Modifications made by concurrent transactions must be isolated from the modifications made by any other concurrent transactions. 用于 ITransaction 中某个操作的隔离级别由执行该操作的 IReliableState 确定。The isolation level used for an operation within an ITransaction is determined by the IReliableState performing the operation.
  • 持续性:事务完成后,其效果永久存在于系统中。Durability: After a transaction has completed, its effects are permanently in place in the system. 即使系统发生故障,修改也会保留。The modifications persist even in the event of a system failure.

隔离级别Isolation levels

隔离级别定义必须从其他事务所作修改中隔离事务的程度。Isolation level defines the degree to which the transaction must be isolated from modifications made by other transactions. Reliable Collections 支持两种隔离级别:There are two isolation levels that are supported in Reliable Collections:

  • 可重复的读取:指定语句不能读取已由其他事务修改但尚未提交的数据,并且指定,其他任何事务都不能在当前事务完成之前修改由当前事务读取的数据。Repeatable Read: Specifies that statements cannot read data that has been modified but not yet committed by other transactions and that no other transactions can modify data that has been read by the current transaction until the current transaction finishes.
  • 快照:指定事务中任何语句读取的数据都是事务开始时便存在的数据的事务上一致的版本。Snapshot: Specifies that data read by any statement in a transaction is the transactionally consistent version of the data that existed at the start of the transaction. 事务只能识别在其开始之前提交的数据修改。The transaction can recognize only data modifications that were committed before the start of the transaction. 在当前事务中执行的语句看不到在当前事务开始以后由其他事务所做的数据修改。Data modifications made by other transactions after the start of the current transaction are not visible to statements executing in the current transaction. 其效果就好像事务中的语句获得了已提交数据的快照,因为该数据在事务开始时就存在。The effect is as if the statements in a transaction get a snapshot of the committed data as it existed at the start of the transaction. 快照跨 Reliable Collections 一致。Snapshots are consistent across Reliable Collections.

Reliable Collections 会在事务创建时根据副本的操作和角色,为指定读取操作自动选择要使用的隔离级别。Reliable Collections automatically choose the isolation level to use for a given read operation depending on the operation and the role of the replica at the time of transaction's creation. 下表描述了用于 Reliable Dictionary 和 Reliable Queue 操作的默认隔离级别。Following is the table that depicts isolation level defaults for Reliable Dictionary and Queue operations.

操作\角色Operation \ Role 主要Primary 次要Secondary
单个实体读取Single Entity Read 可重复的读取Repeatable Read 快照Snapshot
枚举、计数Enumeration, Count 快照Snapshot 快照Snapshot

备注

单个实体操作的常见示例为 IReliableDictionary.TryGetValueAsyncIReliableQueue.TryPeekAsyncCommon examples for Single Entity Operations are IReliableDictionary.TryGetValueAsync, IReliableQueue.TryPeekAsync.

可靠字典和可靠队列都支持“读取写入” 。Both the Reliable Dictionary and the Reliable Queue support Read Your Writes. 换而言之,事务中的任何写入都会对属于同一事务的后续读取可见。In other words, any write within a transaction will be visible to a following read that belongs to the same transaction.

Locks

在可靠集合中,所有事务都严格实施两个阶段的锁定:在以中止或提交操作终止事务之前,该事务不会释放所获取的锁。In Reliable Collections, all transactions implement rigorous two phase locking: a transaction does not release the locks it has acquired until the transaction terminates with either an abort or a commit.

可靠字典对所有单个实体操作使用行级别锁定。Reliable Dictionary uses row-level locking for all single entity operations. Reliable Queue 权衡严格事务性 FIFO 属性的并发。Reliable Queue trades off concurrency for strict transactional FIFO property. 可靠队列使用操作级别锁,允许具有 TryPeekAsync 和/或 TryDequeueAsync 的事务与具有 EnqueueAsync 的事务同时进行。Reliable Queue uses operation-level locks allowing one transaction with TryPeekAsync and/or TryDequeueAsync and one transaction with EnqueueAsync at a time. 请注意,为保留 FIFO,如果 TryPeekAsyncTryDequeueAsync 曾观察到 Reliable Queue 为空,则它们将锁定 EnqueueAsyncNote that to preserve FIFO, if a TryPeekAsync or TryDequeueAsync ever observes that the Reliable Queue is empty, they will also lock EnqueueAsync.

写入操作始终采用排他锁。Write operations always take Exclusive locks. 对于读取操作,锁定取决于几个因素:For read operations, the locking depends on a couple of factors:

  • 使用快照隔离完成的任何读取操作都是无锁的。Any read operation done using Snapshot isolation is lock-free.
  • 任何可重复读取操作默认情况下均采用共享锁。Any Repeatable Read operation by default takes Shared locks.
  • 但是,对于任何支持可重复读取的读取操作,用户可以要求使用更新锁而非共享锁。However, for any read operation that supports Repeatable Read, the user can ask for an Update lock instead of the Shared lock. 更新锁是一种非对称锁,用于防止当多个事务为随后可能进行的更新锁定资源时发生常见的死锁。An Update lock is an asymmetric lock used to prevent a common form of deadlock that occurs when multiple transactions lock resources for potential updates at a later time.

锁兼容性矩阵可在下表中找到:The lock compatibility matrix can be found in the following table:

请求\授予Request \ Granted None 共享Shared 更新Update 排他Exclusive
共享Shared 无冲突No conflict 无冲突No conflict 冲突Conflict ConflictConflict
更新Update 无冲突No conflict 无冲突No conflict 冲突Conflict ConflictConflict
排他Exclusive 无冲突No conflict 冲突Conflict ConflictConflict ConflictConflict

可靠集合 API 中的超时参数用于死锁检测。The timeout argument in Reliable Collections APIs is used for deadlock detection. 例如,两个事务(T1 和 T2)正在尝试读取和更新 K1。For example, two transactions (T1 and T2) are trying to read and update K1. 它们有可能发生死锁,因为它们最后都拥有共享锁。It is possible for them to deadlock, because they both end up having the Shared lock. 在这种情况下,其中一个操作或两个操作都会超时。在这种情况下,更新锁可以防止这种死锁。In this case, one or both of the operations will time out. In this scenario, an Update lock could prevent such a deadlock.

后续步骤Next steps