All Products
Search
Document Center

Tablestore:Use local transactions

Last Updated:Aug 12, 2026

Use the Tablestore SDK for Go to run a local transaction within a partition key value so that all writes in the transaction are committed or discarded together. The isolation level is Read Committed.

Prerequisites

  • Install the Tablestore SDK for Go and initialize the client. Local transactions require version 1.7.8 or later. We recommend that you use the latest version.

  • Local transactions are enabled for the table. You can set EnableLocalTxn when you create a table. To check whether local transactions are enabled for an existing table or to enable them, submit a ticket.

Description

A local transaction is limited to one partition key value. Reads and writes in the transaction share a transaction ID. The workflow has three stages:

  1. Call StartLocalTransaction with a partition key value to create a local transaction and obtain its transaction ID.

  2. Call GetRow, PutRow, UpdateRow, DeleteRow, BatchWriteRow, or GetRange in the transaction and include the transaction ID in each request.

  3. Call CommitTransaction to apply all changes or AbortTransaction to discard the transaction and all changes.

func (client *TableStoreClient) StartLocalTransaction(request *StartLocalTransactionRequest) (*StartLocalTransactionResponse, error)
func (client *TableStoreClient) CommitTransaction(request *CommitTransactionRequest) (*CommitTransactionResponse, error)
func (client *TableStoreClient) AbortTransaction(request *AbortTransactionRequest) (*AbortTransactionResponse, error)

The following sample creates a local transaction for the user-a partition key value, writes a row in the transaction, and commits the transaction.

partitionKey := &tablestore.PrimaryKey{}
partitionKey.AddPrimaryKeyColumn("user_id", "user-a")

startResponse, err := client.StartLocalTransaction(
    &tablestore.StartLocalTransactionRequest{
        TableName:  "example_table",
        PrimaryKey: partitionKey,
    },
)
if err != nil {
    log.Fatal(err)
}
transactionID := startResponse.TransactionId

rowKey := &tablestore.PrimaryKey{}
rowKey.AddPrimaryKeyColumn("user_id", "user-a")
rowKey.AddPrimaryKeyColumn("record_id", int64(1))

change := &tablestore.PutRowChange{
    TableName:     "example_table",
    PrimaryKey:    rowKey,
    TransactionId: transactionID,
}
change.AddColumn("status", "created")
change.SetCondition(tablestore.RowExistenceExpectation_IGNORE)

_, err = client.PutRow(&tablestore.PutRowRequest{PutRowChange: change})
if err != nil {
    _, _ = client.AbortTransaction(
        &tablestore.AbortTransactionRequest{TransactionId: transactionID},
    )
    log.Fatal(err)
}

_, err = client.CommitTransaction(
    &tablestore.CommitTransactionRequest{TransactionId: transactionID},
)
if err != nil {
    log.Fatal(err)
}

Parameters

Create a local transaction

StartLocalTransactionRequest contains the following parameters.

Name

Type

Description

TableName (required)

string

The table name.

PrimaryKey (required)

*PrimaryKey

The partition key value that defines the transaction scope. Specify only the first primary key column of the table.

Data operations in a transaction

PutRowChange, UpdateRowChange, DeleteRowChange, SingleRowQueryCriteria, and RangeRowQueryCriteria contain the following common parameter when used in a transaction.

Name

Type

Description

TransactionId (required)

*string

The local transaction ID returned by StartLocalTransaction. Every read and write in the transaction must include this ID.

Commit or abort a local transaction

CommitTransactionRequest and AbortTransactionRequest contain the following parameter.

Name

Type

Description

TransactionId (required)

*string

The local transaction ID to commit or abort.

Response

StartLocalTransactionResponse contains the following business information.

Field

Type

Description

TransactionId

*string

The new local transaction ID, which is used in data operations and to commit or abort the transaction.

Limitations

  • Auto-increment primary key columns and local transactions cannot be used together.

  • Local transactions use pessimistic locks for concurrency control. During a transaction, writes for the partition key value are locked. Only write requests that carry the transaction ID can succeed. The server releases the write lock when the transaction is committed, aborted, or times out.

  • A transaction can live for up to 60 seconds. If the interval between two operations exceeds 60 seconds, the server automatically aborts the transaction.

  • If a request to create a local transaction times out, the transaction may have already been created on the server. Wait for the transaction to time out before you create another transaction.

  • An uncommitted local transaction may become invalid. If this occurs, retry the operations in the transaction.

  • Only one request can use a transaction ID at a time. Concurrent requests that use the same transaction ID fail.

  • Write requests in the transaction must use the partition key value that was used to create the transaction. Read requests are not subject to this restriction.

  • When you use BatchWriteRow to write rows in a transaction, all rows in the request must belong to the table for which the transaction was created.

  • A transaction can write up to 4 MB of data. The amount of data is accumulated based on the calculation rules for regular write requests.

  • If no version is specified for an attribute column, the server generates the version based on the rules for regular writes when the data is written, not when the transaction is committed.

  • A failed read or write does not invalidate the transaction. You can retry the request or abort the transaction.

Examples

Read a row in a local transaction

The following sample reads a row in an existing local transaction. For a read-only transaction, committing and aborting have the same effect: both release the transaction.

criteria := &tablestore.SingleRowQueryCriteria{
    TableName:     "example_table",
    PrimaryKey:    rowKey,
    MaxVersion:    1,
    TransactionId: transactionID,
}
response, err := client.GetRow(
    &tablestore.GetRowRequest{SingleRowQueryCriteria: criteria},
)
if err != nil {
    log.Fatal(err)
}
fmt.Println(response.Columns)

_, err = client.CommitTransaction(
    &tablestore.CommitTransactionRequest{TransactionId: transactionID},
)
if err != nil {
    log.Fatal(err)
}