Neptune 中的事务隔离级别 - Amazon Neptune
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

Neptune 中的事务隔离级别

Amazon Neptune 为只读查询和更改查询实现了不同的事务隔离级别。基于以下标准,SPARQL 和 Gremlin 查询被划分为只读查询或更改查询:

  • 在 SPARQL 中,读取查询之间有明显的区别(SELECTASKCONSTRUCT, 和DESCRIBE如在中定义的SPARQL 1.1 查询语言规范)和突变查询(INSERTDELETE如在中定义的SPARQL 1.1 更新规范)。

    请注意,Neptune 处理一起提交的多个突变查询(例如,在POST(以分号分隔)作为单个事务。它们作为原子单位保证成功或失败,在失败的情况下,会回滚部分更改。

  • 但是,在 Gremlin 中,Neptune 根据查询是否包含任何查询路径步骤(例如)将查询分类为只读查询或变异查询。addE()addV(),或者drop()操纵数据。如果查询包含任何此类路径步骤,则将其分类为更改查询并执行。

还可以在 Gremlin 中使用长期会话。有关更多信息,请参阅 Gremlin 基于脚本的会话。在此类会话中,所有查询(包括只读查询)都以锁定读取方式执行,就好像它们是更改查询一样。

Neptune 中的只读查询隔离

Neptune 根据快照隔离语义评估只读查询。这意味着,只读查询在开始计算时对数据库的一致性快照进行操作。然后,Neptune 可以保证以下任何现象都不会发生:

  • Dirty reads— Neptune 中的只读查询绝不会看到并发事务中未提交的数据。

  • Non-repeatable reads— 多次读取相同数据的只读事务将始终返回相同的值。

  • Phantom reads— 只读事务绝不会读取到在该事务开始后添加的数据。

由于快照隔离是使用多版本并发控制 (MVCC) 实现的,只读查询不需要锁定数据,因此不会阻止更改查询。

只读副本仅接受只读查询,因此所有针对只读副本的查询均按照 SNAPSHOT 隔离语义执行。

查询只读副本时,唯一需要考虑的其他问题是,写入副本和只读副本之间可能会有较小的复制滞后。这意味着对写入器进行的更新可能需要一个较短的时间才能传播到您正在读取的只读副本。实际的复制时间取决于主实例的写入负载。Amazon Neptune 架构支持低延迟复制,并可在 Amazon 中监测复制滞后。 CloudWatch 指标。

但是,由于隔离级别为 SNAPSHOT,读取查询看到的始终是数据库的一致性状态(即使不是最新的状态)。

如果需要强力保证查询看到的是之前更新的结果,请将查询发送到写入器终端节点本身而不是只读副本。

Neptune 中的突变查询隔离

在更改查询中进行的读取按照 READ COMMITTED 事务隔离执行,这排除了脏读的可能性。超越规定的通常担保READ COMMITTED交易隔离,Neptune 提供了强有力的保证NON-REPEATABLE也不PHANTOM读取可能会发生。

这些强力保证是通过在读取数据时锁定记录和记录范围实现的。这可防止并发事务在被读取后的索引范围内进行插入或删除,从而保证可重复读取。

注意

但是,并发更改事务 Tx2 可在更改事务 Tx1 开始后开始,并且可在 Tx1 锁定并读取数据前提交更改。在这种情况下,Tx1 将看到 Tx2 的更改,就像 Tx2Tx1 开始之前已经完成一样。由于这仅适用于已提交的更改,因此绝不会发生 dirty read

要了解 Neptune 用于突变查询的锁定机制,首先了解 Neptune 的详细信息。图形数据模型索引策略. Neptune 使用三个索引管理数据,即SPOGPOGS, 和GPSO.

为了实现可重复读取READ COMMITTED在交易级别,Neptune 在使用的索引中取消范围锁定。例如,如果更改查询读取名为 person1 的顶点的所有属性和出边,则该节点将在读取数据前锁定由 SPOG 索引中的 S=person1 前缀定义的整个范围。

使用其他索引时,将应用相同的机制。例如,当更改事务使用 POGS 索引在所有源-目标顶点对中查找给定边缘标签时,将锁定 P 位置中该边缘标签的范围。任何并发事务,不管是只读查询还是更改查询,都仍可在锁定范围内执行读取。但是,涉及在锁定的前缀范围内插入或删除新记录的任何更改都需要排他锁,并且将被阻止。

换句话说,当更改事务已读取索引范围时,可以强力保证在该读取事务结束之前,任何并发事务都不会修改该范围。这可保证不会出现 non-repeatable reads

使用锁定等待超时解决冲突

如果第二个事务试图在第一个事务已锁定的范围内修改记录,Neptune 会立即检测到冲突并阻止第二个事务。

如果未检测到依赖性死锁,Neptune 将自动应用锁定等待超时机制,被阻止的事务等待最多 60 秒,以便持有该锁的事务完成并释放锁。

  • 如果锁定等待超时在释放锁前到期,则回滚被阻止的事务。

  • 如果在锁定等待超时之内释放了锁,则第二个事务将被解除阻止,并且可以成功完成而无需重试。

但是,如果 Neptune 检测到两个事务之间存在依赖性死锁,则无法自动协调冲突。在这种情况下,Neptune 将立即取消并回滚第二个事务,而不会启动锁定等待超时。