View a markdown version of this page

Neptune 中的 Gremlin 事务 - Amazon Neptune

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

Neptune 中的 Gremlin 事务

Gremlin 事务的执行上下文有多种。在与 Gremlin 结合使用时,务必了解您所处的上下文及其影响:

  • Script-based – 使用基于文本的 Gremlin 字符串发出请求,如下所示:

    • 使用 Java 驱动程序和 Client.submit(string)

    • 使用 Gremlin 控制台和 :remote connect

    • 使用 HTTP API。

  • Bytecode-based – 请求是使用 Gremlin 语言变体 (GLV) 中典型的序列化的 Gremlin 字节码发出的。

    例如,使用 Java 驱动程序 g = traversal().withRemote(...)

对于上述任一上下文,都有额外的上下文,即请求以无会话或绑定到会话的形式发送。

注意

Gremlin 事务必须始终提交或回滚,这样才能释放服务器端资源。如果在事务过程中出现错误,请务必重试整个事务,而不仅仅是失败的特定请求。

无会话请求

无会话时,请求等同于单个事务。

对于脚本来说,这意味着在单个请求中发送的一条或多条 Gremlin 语句将作为单个事务提交或回滚。例如:

Cluster cluster = Cluster.open(); Client client = cluster.connect(); // sessionless // 3 vertex additions in one request/transaction: client.submit("g.addV();g.addV();g.addV()").all().get();

对于字节码,会对从 g 生成和执行的每个遍历发出无会话请求:

GraphTraversalSource g = traversal().withRemote(...); // 3 vertex additions in three individual requests/transactions: g.addV().iterate(); g.addV().iterate(); g.addV().iterate(); // 3 vertex additions in one single request/transaction: g.addV().addV().addV().iterate();

绑定到会话的请求

绑定到会话时,可以在单个事务的上下文中应用多个请求。

对于脚本来说,这意味着没有必要将所有图形操作串联成单个嵌入式字符串值:

Cluster cluster = Cluster.open(); Client client = cluster.connect(sessionName); // session try { // 3 vertex additions in one request/transaction: client.submit("g.addV();g.addV();g.addV()").all().get(); } finally { client.close(); } try { // 3 vertex additions in three requests, but one transaction: client.submit("g.addV()").all().get(); // starts a new transaction with the same sessionName client.submit("g.addV()").all().get(); client.submit("g.addV()").all().get(); } finally { client.close(); }

对于基于脚本的会话,关闭客户端并client.close()提交事务。基于脚本的会话中没有明确的回滚命令可用。要强制回滚,您可以通过发出查询(例如g.inject(0).fail('rollback')在关闭客户端之前)来导致事务失败。

注意

像这样的g.inject(0).fail('rollback')查询用来故意抛出错误以强制回滚,但在客户端上会产生异常。在关闭客户端之前,捕获并丢弃生成的异常。

对于字节码,可以显式控制事务并透明地管理会话。Gremlin 语言变体 (GLV) 支持 Gremlin 对事务执行 commit()rollback()tx() 语法,如下所示:

GraphTraversalSource g = traversal().withRemote(conn); Transaction tx = g.tx(); // Spawn a GraphTraversalSource from the Transaction. // Traversals spawned from gtx are executed within a single transaction. GraphTraversalSource gtx = tx.begin(); try { gtx.addV('person').iterate(); gtx.addV('software').iterate(); tx.commit(); } finally { if (tx.isOpen()) { tx.rollback(); } }

尽管上面的示例是用 Java 编写的,但您也可以在其他语言中使用此tx()语法。有关特定语言的事务语法,请参阅 Java、Pyth onJavascri pt .NET 和 Go 的 Apache TinkerPop 文档的 “事务” 部分。

警告

无会话只读查询在 SNAPSHOT 隔离下执行,但在显式事务中运行的只读查询则在 SERIALIZABLE 隔离下执行。与在 SNAPSHOT 隔离下运行的只读查询不同,在 SERIALIZABLE 隔离下执行的只读查询会产生更高的开销,并且可能阻塞并发写入或被并发写入阻塞。

字节码提交和回滚的超时行为

tx()语法中使用基于字节码的事务时,commit()rollback()操作不受查询超时设置的约束。通过设置的全局neptune_query_timeout参数和每个查询的超时值均不evaluationTimeout适用于这些操作。在服务器上commit(),在没有时间限制的情况下rollback()运行,直到它们完成或遇到错误。

在客户端,直到服务器做出响应,Gremlin 驱动程序tx.commit()tx.rollback()调用才会完成。根据语言的不同,这可能表现为阻塞调用或未解决的异步操作。没有驱动程序提供限制这些调用的内置超时设置。有关这些事务功能的并发行为的详细信息,请查阅您的特定 Gremlin 语言变体的 API 文档。

重要

如果commit()rollback()调用所花费的时间比预期的长,则可能会因并发事务的锁争用而被阻止。有关锁冲突的更多信息,请参阅使用 Lock-Wait 超时解决冲突

如果您需要限制应用程序等待commit()或的时间rollback(),则可以使用所用语言的并发功能来应用客户端超时。如果触发客户端超时,服务器将继续处理该操作。服务器端操作会保留一个工作线程,直到它完成。在客户端超时后,关闭连接并创建一个新连接,而不是重复使用现有连接,因为事务状态不确定。

Server-side 交易清理

如果客户端在不提交或回滚的情况下断开连接或放弃事务,Neptune 会使用服务器端机制最终清理孤立的事务:

  • Bytecode-based 会@@ 话超时 — 闲置时间超过最大会话生命周期(10 分钟)的会话将被关闭,所有未完成的事务都将被回滚。

  • 连接空闲超时 — Neptune 关闭空闲了大约 20 分钟的 WebSocket 连接。连接关闭后,服务器会回滚与该连接关联的所有未完成的事务。

这些清理机制是安全网。我们建议您在处理完事务后始终明确提交或回滚事务。