---
title: "Data consistency and isolation"
description: "Manage data consistency and isolation in Aerospike Graph Service for read-only and mutation Gremlin queries."
---

# Data consistency and isolation

> For the complete documentation index see: [llms.txt](https://aerospike.com/docs/llms.txt)
> 
> All documentation pages available in markdown.

This page describes how to manage data consistency and isolation with Aerospike Graph Service (AGS).

## Overview

Aerospike Graph Service (AGS) supports different transaction isolation levels for read-only queries and for Gremlin mutation queries. The classification of a Gremlin query depends on whether it modifies graph data:

-   Read-only queries do not alter data.
    
-   Mutation queries modify the graph using operations. If a query contains any of the following mutation steps, it is classified and executed as a mutation query. Otherwise, it is treated as a read-only query.
    
    | Operation | Gremlin step |
    | --- | --- |
    | Create edge | `addE()` |
    | Create vertex | `addV()` |
    | Merge edge | `mergeE()` |
    | Merge vertex | `mergeV()` |
    | Update vertex property | `v(<>).property("key", "value")` |
    | Update edge property | `e(<>).property("key", "value")` |
    | Delete vertex | `v(<>).drop()` |
    | Delete edge | `e(<>).drop()` |
    | Delete vertex property | `v(<>).properties("key").drop()` |
    | Delete edge property | `e(<>).properties("key").drop()` |
    

### Read-only queries

Read-only queries follow an eventual consistency model. This means that if updates occur concurrently on the same vertex or edge, the query results may temporarily reflect stale or inconsistent data due to ongoing mutations during query execution.

### Mutation queries

The consistency of mutation queries depends on whether the Aerospike database namespace is configured with [Strong Consistency (SC)](https://aerospike.com/docs/database/manage/namespace/consistency/) mode or [Available and Partition-tolerant (AP)](https://aerospike.com/docs/database/learn/architecture/clustering/consistency-modes) mode.

-   In SC mode and with AGS transactions [enabled](#enabling-transactions), all mutation queries are **atomic and isolated**, guaranteeing no data loss, even during a cluster split. The only exception is the `drop()` step for a [supernode](https://aerospike.com/docs/graph/2.5.0/develop/query/supernodes) vertex.
    
-   In AP mode some writes may be lost during a cluster split. However, mutations which use the following gremlin steps are **atomic and isolated**:
    
    | Operation | Gremlin step |
    | --- | --- |
    | Create vertex | `addV()` |
    | Update vertex property | `v(<>).property("key", "value")` |
    | Update edge property | `e(<>).property("key", "value")` |
    | Delete vertex property | `v(<>).properties("key").drop()` |
    | Delete edge property | `e(<>).properties("key").drop()` |
    | Merge vertex | `mergeV()` |
    

## Enabling transactions

To ensure write consistency across all supported mutation operations in AGS transactions, you must meet the following requirements and set a configuration option as described in this section.

### Prerequisites

-   Use [Aerospike Enterprise Edition v8.0](https://aerospike.com/products/database/) and later on your database cluster.
    
-   [Configure the namespace](https://aerospike.com/docs/database/manage/namespace/consistency) of your Aerospike database to use strong consistency.
    

### Enable transactions in AGS

To enable transactions in AGS, set the following [configuration options](https://aerospike.com/docs/graph/reference/config):

-   [`aerospike.graph.mrt.enabled`](https://aerospike.com/docs/graph/reference/config#aerospikegraphmrtenabled)
    
    Set this value to `true`.
    
-   [`aerospike.graph.mrt.timeout`](https://aerospike.com/docs/graph/reference/config#aerospikegraphmrttimeout)
    
    Optional value in seconds for transaction timeouts. Maximum allowable value is 120.
    

## Application code considerations

AGS transactions prevent concurrent writes to the same graph elements. Use retry patterns in client code to handle concurrent write situations.

The following code example demonstrates a retry pattern:

```java
for (int i = 0; i < RETRY_COUNT; i++) {

    try {

        // Write operation which may throw an exception from concurrent update.

        g.V(1).drop().iterate();

        break;

    } catch (final Exception e) {

        // Back off exponentially.

        Thread.sleep(Math.min(Math.pow(10, i), 5000));

    }

}
```