Local transactions (partition key-based transactions) can be used to specify that the operations on a partition key are atomic, meaning that operations based on the specified partition key either succeed or fail. The isolation level of the local transaction is serializable.

To use a local transaction, you can use SyncClient#startLocalTransaction to start the transaction on the specified partition key. You can then use StartLocalTransactionResponse#getTransactionId to obtain the transaction ID that can be used to perform operations within the transaction. The following operations are supported for local transactions. All requests that inherit from the TxnRequest class support operations within local transactions:
  • DeleteRow
  • UpdateRow
  • BatchWriteRow
  • GetRange
  • PutRow
  • GetRow

Create a client

The following code provides an example on how to create a client:
SyncClient syncClient = new SyncClient(
    endpoint,            // endpoint
    accessKeyId,         // access_key_id
    accessKeySecret,     // access_key_secret
    instanceName         // instance_name
)

Start, submit, and abort local transactions

  • Start a local transaction
    You can use SyncClient#startLocalTransaction to start a local transaction.
    // Specify a partition key for the local transaction. The partition key is the first primary key.
    PrimaryKey transactionPK = new PrimaryKey(Collections.singletonList(
        new PrimaryKeyColumn(PK_USER_ID, PrimaryKeyValue.fromString(userId))
    ));
    StartLocalTransactionRequest startTransactionRequest = new StartLocalTransactionRequest(TABLE_NAME, transactionPK);
    StartLocalTransactionResponse startTransactionResponse = syncClient.startLocalTransaction(startTransactionRequest);
    // After a transaction is started, a transaction ID is returned. Any request that implements the abstract class TxnRequest can use setTransactionId to specify a transaction.
    final String transactionId = startTransactionResponse.getTransactionID();
  • Submit a local transaction
    // After a local transaction is submitted, all write operations related to the returned transaction ID are stored in Tablestore.
    syncClient.commitTransaction(new CommitTransactionRequest(transactionId));
  • Abort a local transaction
    // After a local transaction is aborted, all write operations related to the returned transaction ID are rolled back.
    syncClient.abortTransaction(new AbortTransactionRequest(transactionId));

Perform operations using the transaction ID

  • Perform write operations through local transactions
    The following code provides an example on how to call the PutRow operation within a transaction. You must perform write operations within the partition key on which the transaction is started. Otherwise, an exception is returned.
    PutRowRequest typeAPutRequest = new PutRowRequest(new RowPutChange(
        TABLE_NAME,
        new PrimaryKey(Arrays.asList(
            new PrimaryKeyColumn(PK_USER_ID, PrimaryKeyValue.fromString(userId)),
            new PrimaryKeyColumn(PK_TYPE, PrimaryKeyValue.fromString(typeA))
        ))
    ).addColumn(COLUMN_CONTENT, ColumnValue.fromString("content_a")));
    // Specify the transaction ID. You can use StartLocalTransactionResponse#getTransactionId to obtain the transaction ID.
    typeAPutRequest.setTransactionId(transactionId);
    syncClient.putRow(typeAPutRequest);
    Note You cannot use read operations such as GetRange and GetRow to read data that has been modified but has not been committed in other transactions.
  • Perform read operations through local transactions
    You can perform read operations within a transaction. For example, you must read data before you modify the data.The following code provides an example on how to call the GetRow operation within a transaction. To use a local transaction, you must call the GetRow operation within the partition key on which the transaction is started.
    GetRowRequest getRowRequest = new GetRowRequest();
    SingleRowQueryCriteria singleRowQueryCriteria = new SingleRowQueryCriteria(
        TABLE_NAME,
        new PrimaryKey(Arrays.asList(
            new PrimaryKeyColumn(PK_USER_ID, PrimaryKeyValue.fromString(userId)),
            new PrimaryKeyColumn(PK_TYPE, PrimaryKeyValue.fromString(typeA))
        ))
    );
    singleRowQueryCriteria.setMaxVersions(1);
    getRowRequest.setRowQueryCriteria(singleRowQueryCriteria);
    // Specify the transaction ID.
    getRowRequest.setTransactionId(transactionId);
    GetRowResponse getRowResponse = syncClient.getRow(getRowRequest);