

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# Neptune openCypher 中的交易
<a name="access-graph-opencypher-transactions"></a>

Amazon Neptune 中的 OpenCypher 實作會使用 [Neptune 定義的交易語義](transactions-neptune.md)。不過，Bolt 驅動程式提供的隔離層級對 Bolt 交易語義有一些特定的含意，如以下各節所述。

## 唯讀 Bolt 交易查詢
<a name="access-graph-opencypher-transactions-ro"></a>

有各種方式可以處理唯讀查詢，其中具有不同的交易模型和隔離層級，如下所示：

### 隱含唯讀交易查詢
<a name="access-graph-opencypher-transactions-ro-implicit"></a>

以下是唯讀隱含交易的範例：

```
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` 隔離語義下將讀取隱含交易評估為[唯讀查詢](transactions-neptune.md#transactions-neptune-read-only)。

若失敗，預設會重試讀取隱含交易。

### 自動遞交唯讀交易查詢
<a name="access-graph-opencypher-transactions-ro-autocommit"></a>

以下是唯讀自動遞交交易的範例：

```
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` 隔離語義下將自動遞交交易查詢評估為[唯讀查詢](transactions-neptune.md#transactions-neptune-read-only)。請注意，僅供讀取複本只接受唯讀查詢。

如果您沒有傳入工作階段設定，則預設會在變動查詢隔離的情況下處理自動遞交查詢，因此務必傳入明確將存取模式設定為 `READ` 的工作階段組態。

若失敗，不會重試唯讀自動遞交查詢。

### 明確唯讀交易查詢
<a name="access-graph-opencypher-transactions-ro-explicit"></a>

以下為明確唯讀交易的範例：

```
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` 隔離語義下將明確唯讀交易評估為[唯讀查詢](transactions-neptune.md#transactions-neptune-read-only)。請注意，僅供讀取複本只接受唯讀查詢。

如果您沒有傳入工作階段設定，則預設會在變動查詢隔離的情況下處理唯讀交易，因此務必傳入明確將存取模式設定為 `READ` 的工作階段組態。

若失敗，預設會重試唯讀明確查詢。

## 變動 Bolt 交易查詢
<a name="access-graph-opencypher-transactions-wr"></a>

與唯讀查詢一樣，有各種方式可以處理變動查詢，其中具有不同的交易模型和隔離層級，如下所示：

### 隱含變動交易查詢
<a name="access-graph-opencypher-transactions-wr-implicit"></a>

以下為隱含變動交易的範例：

```
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 變動交易](transactions-neptune.md#transactions-neptune-mutation)的一般保證。

無論您是否特別傳入工作階段組態，一律都會將交易視為寫入交易。

如需衝突，請參閱 [使用鎖定等待逾時的衝突解決機制](transactions-neptune.md#transactions-neptune-conflicts)。

### 自動遞交變動交易查詢
<a name="access-graph-opencypher-transactions-wr-autocommit"></a>

變動自動遞交查詢會繼承與變動隱含交易相同的行為。

如果您沒有傳入工作階段組態，預設會將交易視為寫入交易。

若失敗，不會自動重試變動自動遞交查詢。

### 明確變動交易查詢
<a name="access-graph-opencypher-transactions-wr-explicit"></a>

以下為明確變動交易的範例：

```
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();
}
```

明確變動查詢會繼承與隱含變動交易相同的行為。

如果您沒有傳入工作階段組態，預設會將交易視為寫入交易。

如需衝突，請參閱 [使用鎖定等待逾時的衝突解決機制](transactions-neptune.md#transactions-neptune-conflicts)。