

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# Neptune での Gremlin トランザクション
<a name="access-graph-gremlin-transactions"></a>

Gremlin [トランザクション](transactions.md)が実行されるコンテキストはいくつかあります。Gremlin を使用する際には、作業対象となるコンテキストとその意味を理解することが重要です。
+ **`Script-based`** — リクエストは、次のようなテキストベースの Gremlin 文字列を使用して行われます。
  + Java ドライバーと `Client.submit({{string}})` の使用。
  + Gremlin コンソールと `:remote connect` の使用。
  + バルク API の使用。
+ **`Bytecode-based`** — リクエストは、[Gremlin 言語バリアント](https://tinkerpop.apache.org/docs/current/reference/#gremlin-drivers-variants) (GLV) のシリアル化された Gremlin バイトコードを使用して行われます。

  例えば、Java ドライバー `g = traversal().withRemote({{...}})` を使用する場合などです。

上記のコンテキストのどちらでも、リクエストがセッションレスまたはセッションにバインドされた状態で送信されるという追加のコンテキストがあります。

**注記**  
 Gremlin トランザクションは、サーバー側のリソースを解放できるように、常にコミットまたはロールバックする必要があります。トランザクション中にエラーが発生した場合は、失敗した特定のリクエストだけでなく、トランザクション全体を再試行することが重要です。

## セッションレスリクエスト
<a name="access-graph-gremlin-transactions-sessionless"></a>

 セッションレスの場合、リクエストは 1 回のトランザクションに相当します。

スクリプトの場合、1 回のリクエストで送信された 1 つ以上の Gremlin ステートメントが 1 つのトランザクションとしてコミットまたはロールバックされることを意味します。例えば、次のようになります。

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

## セッションにバインドされたリクエスト
<a name="access-graph-gremlin-transactions-session-bound"></a>

セッションにバインドすると、1 つのトランザクションのコンテキスト内で複数のリクエストを適用できます。

スクリプトの場合、すべてのグラフ操作を連結して 1 つの埋め込み文字列値にする必要がないということです。

```
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 の `tx()` 構文をサポートして、トランザクションを `commit()` または `rollback()` します。

```
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](https://tinkerpop.apache.org/docs/current/reference/#gremlin-java-transactions)、[Python](https://tinkerpop.apache.org/docs/current/reference/#gremlin-python-transactions)、[Javascript](https://tinkerpop.apache.org/docs/current/reference/#gremlin-javascript-transactions)、[.NET](https://tinkerpop.apache.org/docs/current/reference/#gremlin-dotnet-transactions)、[Go](https://tinkerpop.apache.org/docs/current/reference/#gremlin-go-transactions) に関する Apache TinkerPop ドキュメントの「トランザクション」セクションを参照してください。

**警告**  
セッションレス読み取り専用クエリは [SNAPSHOT](transactions-isolation-levels.md) 分離下で実行されますが、明示的なトランザクション内で実行される読み取り専用クエリは [SERIALIZABLE](transactions-isolation-levels.md) 分離下で実行されます。`SERIALIZABLE` 分離下で実行される読み取り専用クエリは、`SNAPSHOT` 分離下で実行されるクエリとは異なり、オーバーヘッドが大きくなり、同時書き込みによってブロックしたり、ブロックされたりする可能性があります。

## バイトコードコミットとロールバックのタイムアウト動作
<a name="access-graph-gremlin-transactions-commit-rollback-timeout"></a>

`tx()` 構文でバイトコードベースのトランザクションを使用する場合、 `commit()` および `rollback()`オペレーションはクエリタイムアウト設定の対象になりません。グローバル`neptune_query_timeout`パラメータも、 で設定されたクエリごとのタイムアウト値も、これらのオペレーション`evaluationTimeout`には適用されません。サーバーで、完了するかエラーが発生するまで、時間制限なしで `commit()`と `rollback()`を実行します。

クライアント側では、サーバーが応答するまで Gremlin ドライバーの `tx.commit()`および `tx.rollback()`呼び出しは完了しません。言語によっては、これはブロック呼び出しまたは未解決の非同期オペレーションとして現れる場合があります。これらの呼び出しをバインドする組み込みタイムアウト設定を提供するドライバーはありません。これらのトランザクション機能に関する同時実行動作の詳細については、特定の Gremlin 言語バリアントの API ドキュメントを参照してください。

**重要**  
`commit()` または `rollback()`呼び出しに予想以上に時間がかかる場合、同時トランザクションからのロック競合によってブロックされる可能性があります。ロックの競合の詳細については、「」を参照してください[ロック待機タイムアウトを使用した競合の解決](transactions-neptune.md#transactions-neptune-conflicts)。

アプリケーションが `commit()`または を待機する時間をバインドする必要がある場合は`rollback()`、言語の同時実行機能を使用してクライアント側のタイムアウトを適用できます。クライアント側のタイムアウトが発生した場合、サーバーはオペレーションの処理を続行します。サーバー側のオペレーションは、完了するまでワーカースレッドを保持します。クライアント側のタイムアウト後、トランザクションの状態が不確定であるため、既存の接続を再利用するのではなく、接続を閉じて新しい接続を作成します。

### サーバー側のトランザクションクリーンアップ
<a name="access-graph-gremlin-transactions-server-side-cleanup"></a>

クライアントがコミットまたはロールバックせずにトランザクションを切断または中止した場合、Neptune にはサーバー側のメカニズムがあり、最終的に孤立したトランザクションをクリーンアップします。
+ **セッションタイムアウト**   – 最大セッション有効期間 (10 分) を超えてアイドル状態のままになっている バイトコードベースのセッションは閉じられ、開いているトランザクションはすべてロールバックされます。
+ **接続アイドルタイムアウト**   –   Neptune は、約 20 分間アイドル状態の WebSocket 接続を閉じます。接続が終了すると、サーバーはその接続に関連付けられた開いているトランザクションをロールバックします。

これらのクリーンアップメカニズムはセーフティネットです。トランザクションが終了したら、常に明示的にコミットまたはロールバックすることをお勧めします。