

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

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

有數個內容，Gremlin [交易](transactions.md)會在其中執行。使用 Gremlin 時，務必了解您正在其中運作的內容以及其含義：
+ **`Script-based`** – 請求是使用文字型 Gremlin 字串提出的，如下所示：
  + 使用 Java 驅動程式和 `Client.submit({{string}})`。
  + 使用 Gremlin 主控台和 `:remote connect`。
  + 使用 HTTP API。
+ **`Bytecode-based`** – 請求是使用 [Girmlin 語言變體](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>

 無工作階段時，請求等同於單一交易。

對於指令碼，其含義是單一請求中傳送的一個或多個 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();
```

## 繫結至工作階段的請求
<a name="access-graph-gremlin-transactions-session-bound"></a>

當繫結至工作階段時，可在單一交易的內容中套用多個請求。

對於指令碼，含義是不需要將所有圖形操作串連成單一內嵌字串值：

```
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) 支援 `commit()` 或 `rollback()` 交易的 Gremlin `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](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 連線。當連線關閉時，伺服器會復原與該連線相關聯的任何開啟交易。

這些清除機制是安全網路。我們建議您在完成交易時，一律明確遞交或轉返交易。