All Products
Search
Document Center

Tablestore:Use the local transaction feature

Last Updated:Dec 27, 2023

After you enable the local transaction feature for a data table, you can create a local transaction based on the specified partition key value and perform read and write operations on the data in the local transaction. You can use the local transaction feature to perform atomic operations to read and write one or more rows. Pessimistic locking is used to control concurrent operations in a local transaction.

Important

If you use Tablestore SDK for Java V5.11.0 or later, you can enable the local transaction feature when you create a data table. For more information, see Create a data table.

You can use a local transaction to specify that the operations on data that shares the same partition key either all succeed or all fail. The isolation level of the local transaction is Read Committed.

Prerequisites

  • An OTSClient instance is initialized. For more information, see Initialize a client.

  • A data table is created, and data is written to the data table.

Procedure

  1. Call the StartLocalTransaction operation to create a local transaction based on the specified partition key value and obtain the local transaction ID.

  2. Read and write data in the local transaction.

    You can call the GetRow, PutRow, DeleteRow, UpdateRow, BatchWriteRow, and GetRange operations to perform operations on data in the local transaction.

  3. Call the CommitTransaction operation to commit the local transaction, or call the AbortTransaction operation to abort the local transaction.

Limits

  • The validity period of a local transaction is up to 60 seconds.

    If a transaction is not committed or aborted within 60 seconds, the Tablestore server determines that the transaction times out and aborts the transaction.

  • A transaction may be created on the Tablestore server even if a timeout error is returned. In this case, you can resend a transaction creation request after the created transaction times out.
  • If a local transaction is not committed, it may become invalid. In this case, retry the operation within this transaction.
  • Tablestore imposes the following limits on read and write operations on data within a local transaction:
    • The transaction ID cannot be used to access data beyond the range specified based on the partition key value that is used to create the transaction.
    • The partition key values of all write requests in the same transaction must be the same as the partition key value used to create the transaction. This limit does not apply to read requests.
    • A local transaction can be used only by one request at a time. When the transaction is in use, other operations that use the transaction ID fail.
    • The maximum interval for read and write operations on data within a transaction is 60 seconds.

      If a transaction is not read or written for more than 60 seconds, the Tablestore server determines that the transaction times out and aborts the transaction.

    • Up to 4 MB of data can be written to each transaction. The volume of data written to each transaction is calculated in the same way as a regular write request.
    • If you do not specify a version number for a cell, the Tablestore server assigns a version number to the cell in the usual way when the cell is written to the transaction (rather than when the transaction is committed).
    • If a BatchWriteRow request includes a transaction ID, all rows in the request can be written only to the table that matches the transaction ID.
    • When you use a local transaction, a write lock is added to the data of the partition key value based on which the local transaction is created. Only write requests that contain the local transaction ID and are initiated to write data within the local transaction are successful. Other non-transactional requests or write requests that contain the IDs of other local transactions and are initiated to write data within the local transaction fail. Data within the transaction is unlocked when the transaction is committed or aborted, or when the transaction times out.
    • A transaction remains valid even if a read or write request with the transaction ID is rejected. You can specify a retry rule to resend the request, or you can abort the transaction.

Parameters

Parameter

Description

TableName

The name of the data table.

PrimaryKey

The primary key of the data table.

  • You must specify a partition key value when you create a local transaction.

  • You must specify all primary key columns when you read and write data in a local transaction.

TransactionId

The local transaction ID that uniquely identifies a local transaction.

You must specify a local transaction ID when you read and write data in a local transaction.

Sample code

Use the local transaction feature to write a data row

The following sample code shows how to create a local transaction based on the specified partition key value in a table and how to write a data row in the local transaction:

private static void transactionPutRow(SyncClient client) {
    // Specify the name of the data table. 
    String tableName="<TABLE_NAME>";
    // Create a local transaction based on the specified partition key value.  
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    // Specify the column name, data type, and column value of the partition key. 
    primaryKeyBuilder.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromString("pkvalue"));
    PrimaryKey primaryKey = primaryKeyBuilder.build();
    // Construct a request to create a local transaction. 
    StartLocalTransactionRequest request = new StartLocalTransactionRequest(tableName, primaryKey);
    // Initiate the request to create a local transaction and obtain the local transaction ID. 
    String txnId = client.startLocalTransaction(request).getTransactionID();
    
    // Write a data row in the local transaction. 
    // Configure the primary key information of the row. 
    PrimaryKeyBuilder primaryKeyBuilder1 = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    // Specify the column name, data type, and column value of the primary key. If the primary key of the table consists of multiple primary key columns, configure the information about the primary key columns in sequence. 
    primaryKeyBuilder1.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromString("pkvalue"));
    primaryKeyBuilder1.addPrimaryKeyColumn("pk2", PrimaryKeyValue.fromLong(10001));
    PrimaryKey primaryKey1 = primaryKeyBuilder1.build();
    // Configure the attribute columns of the row. 
    RowPutChange rowPutChange = new RowPutChange(tableName, primaryKey1);
    // Specify the column name, data type, and column value of each attribute column. Add more attribute columns as required. 
    rowPutChange.addColumn(new Column("col1", ColumnValue.fromString("colvalue")));
    rowPutChange.addColumn(new Column("col2", ColumnValue.fromLong(10)));
    PutRowRequest request1 = new PutRowRequest(rowPutChange);
    // Pass the local transaction ID to the request. 
    request1.setTransactionId(txnId);
    client.putRow(request1);
    
    // Commit or abort the local transaction.  
    // Commit the local transaction so that all data modifications in the local transaction take effect. 
    CommitTransactionRequest commitRequest = new CommitTransactionRequest(txnId);
    client.commitTransaction(commitRequest);
    // Abort the local transaction so that all data modifications in the local transaction do not take effect. 
    //AbortTransactionRequest abortRequest = new AbortTransactionRequest(txnId);
    //client.abortTransaction(abortRequest);
}

Use the local transaction feature to read a data row

The following sample code shows how to create a local transaction based on the specified partition key value in a table and how to read a data row in the local transaction:

private static void transactionGetRow(SyncClient client) {
    // Specify the name of the data table. 
    String tableName="exampletabled";
    // Create a local transaction based on the specified partition key value. 
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    // Specify the column name, data type, and column value of the partition key. 
    primaryKeyBuilder.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromString("111"));
    PrimaryKey primaryKey = primaryKeyBuilder.build();
    // Construct a request to create a local transaction. 
    StartLocalTransactionRequest request = new StartLocalTransactionRequest(tableName, primaryKey);
    // Initiate the request to create a local transaction and obtain the local transaction ID. 
    String txnId = client.startLocalTransaction(request).getTransactionID();

    // Read a data row in the local transaction. 
    // Configure the primary key information of the row. 
    PrimaryKeyBuilder primaryKeyBuilder1 = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    // Specify the column name, data type, and column value of the primary key. If the primary key of the table consists of multiple primary key columns, configure the information about the primary key columns in sequence. 
    primaryKeyBuilder1.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromString("111"));
    primaryKeyBuilder1.addPrimaryKeyColumn("pk2", PrimaryKeyValue.fromLong(10001));
    PrimaryKey primaryKey1 = primaryKeyBuilder1.build();
    SingleRowQueryCriteria criteria = new SingleRowQueryCriteria(tableName, primaryKey1);
    // Read the latest version of data. 
    criteria.setMaxVersions(1);
    GetRowRequest request1 = new GetRowRequest(criteria);
    // Pass the local transaction ID to the request. 
    request1.setTransactionId(txnId);
    GetRowResponse getRowResponse = client.getRow(request1);
  
    // Commit or abort the local transaction. For a read operation, committing or aborting a local transaction has the same effect. 
    // Commit the local transaction so that all data modifications in the local transaction take effect. 
    CommitTransactionRequest commitRequest = new CommitTransactionRequest(txnId);
    client.commitTransaction(commitRequest);
    // Abort the local transaction so that all data modifications in the local transaction do not take effect. 
    //AbortTransactionRequest abortRequest = new AbortTransactionRequest(txnId);
    //client.abortTransaction(abortRequest);
    
    // Obtain and display the data row. 
    Row row = getRowResponse.getRow();
    System.out.println("The data row is read and displayed as follows:");
    System.out.println(row);
}

References

If you want to write multiple data rows at a time or read data whose partition key values are in the specified range, create a local transaction. Then, refer to the sample code provided in the Write data or Read data topic to initiate a request with the local transaction ID included in the request.