本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
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(); }
显式突变查询继承与隐式突变事务相同的行为。
如果未传入会话配置,默认情况下,该事务将被视为写入事务。
有关冲突,请参阅使用锁定等待超时解决冲突。