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

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

Neptune openCypher 中的事务

Amazon Neptune 中的 openCypher 实现使用 Neptune 定义的事务语义。但是,如以下各节所述,Bolt 驱动程序提供的隔离级别对 Bolt 事务语义有一些特定的影响。

只读 Bolt 事务查询

可以处理只读查询的方式多种多样,并可使用不同的事务模型和隔离级别,如下所示:

隐式只读事务查询

以下是只读隐式事务的示例:

public void executeReadImplicitTransaction() { // end point final String END_POINT = "(End Point URL)"; // read query final String READ_QUERY = "MATCH (n) RETURN n limit 10"; // create the driver final Driver driver = GraphDatabase.driver(END_POINT, AuthTokens.none(), Config.builder().withEncryption() .withTrustStrategy(TrustStrategy.trustSystemCertificates()) .build()); // create the session config SessionConfig sessionConfig = SessionConfig.builder() .withFetchSize(1000) .withDefaultAccessMode(AccessMode.READ) .build(); // run the query as access mode read driver.session(sessionConfig).readTransaction(new TransactionWork<String>() { final StringBuilder resultCollector = new StringBuilder(); @Override public String execute(final Transaction tx) { // execute the query Result queryResult = tx.run(READ_QUERY); // Read the result for (Record record : queryResult.list()) { for (String key : record.keys()) { resultCollector.append(key) .append(":") .append(record.get(key).asNode().toString()); } } return resultCollector.toString(); } } ); // close the driver. driver.close(); }

由于只读副本仅接受只读查询,因此,无论在会话配置中设置的访问模式如何,所有针对只读副本的查询都将作为读取隐式事务执行。Neptune 在 SNAPSHOT 隔离语义下将读取隐式事务计算为只读查询

如果失败,默认情况下会重试读取隐式事务。

自动提交只读事务查询

以下是只读自动提交事务的示例:

public void executeAutoCommitTransaction() { // end point final String END_POINT = "(End Point URL)"; // read query final String READ_QUERY = "MATCH (n) RETURN n limit 10"; // Create the session config. final SessionConfig sessionConfig = SessionConfig .builder() .withFetchSize(1000) .withDefaultAccessMode(AccessMode.READ) .build(); // create the driver final Driver driver = GraphDatabase.driver(END_POINT, AuthTokens.none(), Config.builder() .withEncryption() .withTrustStrategy(TrustStrategy.trustSystemCertificates()) .build()); // result collector final StringBuilder resultCollector = new StringBuilder(); // create a session final Session session = driver.session(sessionConfig); // run the query final Result queryResult = session.run(READ_QUERY); for (final Record record : queryResult.list()) { for (String key : record.keys()) { resultCollector.append(key) .append(":") .append(record.get(key).asNode().toString()); } } // close the session session.close(); // close the driver driver.close(); }

如果在会话配置中将访问模式设置为 READ,则 Neptune 会在 SNAPSHOT 隔离语义下将自动提交事务查询计算为只读查询。请注意,只读副本仅接受只读查询。

如果您未传入会话配置,则默认情况下会使用突变查询隔离来处理自动提交查询,因此传入将访问模式显式设置为 READ 的会话配置非常重要。

如果失败,则不会重试只读自动提交查询。

显式只读事务查询

以下是显式只读事务的示例:

public void executeReadExplicitTransaction() { // end point final String END_POINT = "(End Point URL)"; // read query final String READ_QUERY = "MATCH (n) RETURN n limit 10"; // Create the session config. final SessionConfig sessionConfig = SessionConfig .builder() .withFetchSize(1000) .withDefaultAccessMode(AccessMode.READ) .build(); // create the driver final Driver driver = GraphDatabase.driver(END_POINT, AuthTokens.none(), Config.builder() .withEncryption() .withTrustStrategy(TrustStrategy.trustSystemCertificates()) .build()); // result collector final StringBuilder resultCollector = new StringBuilder(); // create a session final Session session = driver.session(sessionConfig); // begin transaction final Transaction tx = session.beginTransaction(); // run the query on transaction final List<Record> list = tx.run(READ_QUERY).list(); // read the result for (final Record record : list) { for (String key : record.keys()) { resultCollector .append(key) .append(":") .append(record.get(key).asNode().toString()); } } // commit the transaction and for rollback we can use beginTransaction.rollback(); tx.commit(); // close the driver driver.close(); }

如果在会话配置中将访问模式设置为 READ,则 Neptune 会在 SNAPSHOT 隔离语义下将显式只读事务计算为只读查询。请注意,只读副本仅接受只读查询。

如果您未传入会话配置,则默认情况下会使用突变查询隔离来处理显式只读事务,因此传入将访问模式显式设置为 READ 的会话配置非常重要。

如果失败,默认情况下会重试只读显式查询。

突变 Bolt 事务查询

与只读查询一样,可以通过多种方式处理突变查询,并可使用不同的事务模型和隔离级别,如下所示:

隐式突变事务查询

以下是隐式突变事务的示例:

public void executeWriteImplicitTransaction() { // end point final String END_POINT = "(End Point URL)"; // create node with label as label and properties. final String WRITE_QUERY = "CREATE (n:label {name : 'foo'})"; // Read the vertex created with label as label. final String READ_QUERY = "MATCH (n:label) RETURN n"; // create the driver final Driver driver = GraphDatabase.driver(END_POINT, AuthTokens.none(), Config.builder() .withEncryption() .withTrustStrategy(TrustStrategy.trustSystemCertificates()) .build()); // create the session config SessionConfig sessionConfig = SessionConfig .builder() .withFetchSize(1000) .withDefaultAccessMode(AccessMode.WRITE) .build(); final StringBuilder resultCollector = new StringBuilder(); // run the query as access mode write driver.session(sessionConfig).writeTransaction(new TransactionWork<String>() { @Override public String execute(final Transaction tx) { // execute the write query and consume the result. tx.run(WRITE_QUERY).consume(); // read the vertex written in the same transaction final List<Record> list = tx.run(READ_QUERY).list(); // read the result for (final Record record : list) { for (String key : record.keys()) { resultCollector .append(key) .append(":") .append(record.get(key).asNode().toString()); } } return resultCollector.toString(); } }); // at the end, the transaction is automatically committed. // close the driver. driver.close(); }

作为突变查询一部分进行的读取是在 READ COMMITTED 隔离下执行的,对 Neptune 突变事务具有通常的保证。

无论您是否专门传入会话配置,该事务始终被视为写入事务。

有关冲突,请参阅使用锁定等待超时解决冲突

自动提交突变事务查询

突变自动提交查询继承与突变隐式事务相同的行为。

如果未传入会话配置,默认情况下,该事务将被视为写入事务。

如果失败,则不会自动重试突变自动提交查询。

显式突变事务查询

以下是显式突变事务的示例:

public void executeWriteExplicitTransaction() { // end point final String END_POINT = "(End Point URL)"; // create node with label as label and properties. final String WRITE_QUERY = "CREATE (n:label {name : 'foo'})"; // Read the vertex created with label as label. final String READ_QUERY = "MATCH (n:label) RETURN n"; // create the driver final Driver driver = GraphDatabase.driver(END_POINT, AuthTokens.none(), Config.builder() .withEncryption() .withTrustStrategy(TrustStrategy.trustSystemCertificates()) .build()); // create the session config SessionConfig sessionConfig = SessionConfig .builder() .withFetchSize(1000) .withDefaultAccessMode(AccessMode.WRITE) .build(); final StringBuilder resultCollector = new StringBuilder(); final Session session = driver.session(sessionConfig); // run the query as access mode write final Transaction tx = driver.session(sessionConfig).beginTransaction(); // execute the write query and consume the result. tx.run(WRITE_QUERY).consume(); // read the result from the previous write query in a same transaction. final List<Record> list = tx.run(READ_QUERY).list(); // read the result for (final Record record : list) { for (String key : record.keys()) { resultCollector .append(key) .append(":") .append(record.get(key).asNode().toString()); } } // commit the transaction and for rollback we can use tx.rollback(); tx.commit(); // close the session session.close(); // close the driver. driver.close(); }

显式突变查询继承与隐式突变事务相同的行为。

如果未传入会话配置,默认情况下,该事务将被视为写入事务。

有关冲突,请参阅使用锁定等待超时解决冲突