Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions docusaurus-docs/docs/clients/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,34 @@ transactions conflict when both transactions:

When a transaction is aborted, all its changes are discarded. Transactions can be manually aborted.

#### Abort reasons

A write-write conflict is not the only reason a commit can abort. When Dgraph
aborts a commit it now reports a *category* describing why, so clients can decide
how to react (for example, retry immediately versus back off). The category is
carried as a `"<code>: <detail>"` prefix on the gRPC `ABORTED` status message
(and on the HTTP error message), where `<code>` is one of:

- `conflict` — a write-write conflict with another concurrent transaction, as
described above. Retrying the transaction typically succeeds.
- `stale-startts` — the transaction's start timestamp predates the current Zero
leader's lease (for example, after a leader change). Retrying with a fresh
transaction succeeds.
- `predicate-move` — a predicate the transaction wrote is being moved between
groups, so commits on it are temporarily blocked. Retrying once the move
completes succeeds.

For example, a conflict abort carries the message
`conflict: Transaction has been aborted. Please retry`.

:::note
Older Dgraph servers do not emit a category prefix. Clients that parse the
reason degrade gracefully and report it as `UNKNOWN` in that case, so existing
error handling keeps working unchanged.
:::

The official [Java](/clients/java) and [Python](/clients/python) clients parse
this category into a typed enum; see those pages for the API.


### In this section
38 changes: 38 additions & 0 deletions docusaurus-docs/docs/clients/java.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,44 @@ client.loginIntoNamespace("groot", "password", 123);

Once logged in, the client can perform all operations allowed for that user in the specified namespace.

## Handling aborted transactions

When a commit aborts, the client throws a `TxnConflictException`. In addition to
the full server message, the exception exposes the [abort reason](/clients#abort-reasons)
as a typed `TxnConflictException.AbortReason`, so you can branch on *why* the
commit aborted:

```java
import io.dgraph.TxnConflictException;
import io.dgraph.TxnConflictException.AbortReason;

Transaction txn = client.newTransaction();
try {
// ... mutations ...
txn.commit();
} catch (TxnConflictException e) {
switch (e.getReason()) {
case CONFLICT:
case STALE_STARTTS:
// Safe to retry with a fresh transaction.
break;
case PREDICATE_MOVE:
// A predicate is being moved between groups; retry after a short backoff.
break;
case UNKNOWN:
// No category reported (e.g. an older server). Fall back to the message.
break;
}
System.err.println("commit aborted: " + e.getMessage());
} finally {
txn.discard();
}
```

`getReason()` returns `AbortReason.UNKNOWN` when the server reports no category,
so the code above works unchanged against older Dgraph servers. `isRetryable()`
remains available for code that only needs the retry/no-retry distinction.

## Documentation

For complete API documentation, examples, and advanced usage:
Expand Down
31 changes: 31 additions & 0 deletions docusaurus-docs/docs/clients/python.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,37 @@ client.login_into_namespace("groot", "password", "123")

Once logged in, the client can perform all operations allowed for that user in the specified namespace.

## Handling aborted transactions

When a commit aborts, the client raises `pydgraph.AbortedError`. In addition to
the full server message, the error exposes the [abort reason](/clients#abort-reasons)
as a typed `pydgraph.AbortReason`, so you can branch on *why* the commit aborted:

```python
import pydgraph

txn = client.txn()
try:
txn.mutate(set_obj={"name": "Alice"})
txn.commit()
except pydgraph.AbortedError as e:
if e.reason in (pydgraph.AbortReason.CONFLICT, pydgraph.AbortReason.STALE_STARTTS):
# Safe to retry with a fresh transaction.
...
elif e.reason == pydgraph.AbortReason.PREDICATE_MOVE:
# A predicate is being moved between groups; retry after a short backoff.
...
else: # pydgraph.AbortReason.UNKNOWN
# No category reported (e.g. an older server). Fall back to the message.
...
print("commit aborted:", e)
finally:
txn.discard()
```

`AbortedError.reason` is `pydgraph.AbortReason.UNKNOWN` when the server reports no
category, so the code above works unchanged against older Dgraph servers.

## Documentation

For complete API documentation, examples, and advanced usage:
Expand Down
22 changes: 21 additions & 1 deletion docusaurus-docs/docs/clients/raw-http.md
Original file line number Diff line number Diff line change
Expand Up @@ -399,14 +399,34 @@ If another client were to perform another transaction concurrently affecting the
"errors": [
{
"code": "Error",
"message": "Transaction has been aborted. Please retry."
"message": "conflict: Transaction has been aborted. Please retry."
}
]
}
```

In this case, it should be up to the user of the client to decide if they wish to retry the transaction.

The `message` is prefixed with a `"<code>: <detail>"` category describing why the
commit aborted, so a client can react appropriately. The `<code>` is one of:

| Code | Meaning |
| ---------------- | ----------------------------------------------------------------------------------------- |
| `conflict` | Write-write conflict with another concurrent transaction. Retrying typically succeeds. |
| `stale-startts` | The transaction's start timestamp predates the current Zero leader's lease (e.g. a leader change). Retry with a fresh transaction. |
| `predicate-move` | A predicate the transaction wrote is being moved between groups, blocking commits on it. Retry after the move completes. |

For example, a stale start-timestamp abort returns
`stale-startts: Transaction has been aborted due to a leader change. Please retry`,
and a blocked predicate move returns
`predicate-move: Commits on predicate <name> are blocked due to predicate move`.

:::note
Older Dgraph servers return the bare detail with no category prefix (e.g.
`Transaction has been aborted. Please retry.`). Clients should treat a missing or
unrecognized prefix as an unknown reason rather than failing to parse.
:::

### Abort the Transaction

To abort a transaction, use the same `/commit` endpoint with the `abort=true` parameter while specifying the `startTs` value for the transaction:
Expand Down