If you want to use a counter for your online application, you can use the atomic counter feature. To use this feature, specify a column as an atomic counter and perform atomic counter operations on the column.
Prerequisites
An OTSClient instance is initialized. For more information, see Initialize an OTSClient instance.
A data table is created, and data is written to the data table.
Usage notes
You can implement atomic counters only on INTEGER columns.
If a column that is specified as an atomic counter does not exist before you write data, the default value of the column is 0. If a column that is specified as an atomic counter is not an INTEGER column, an OTSParameterInvalid error occurs.
You can update an atomic counter by using a positive or negative number, but you must avoid an integer overflow. If an integer overflow occurs, an OTSParameterInvalid error is returned.
By default, the value of an atomic counter is not returned in the response to an update row request. You can specify that the updated value of an atomic counter is returned.
You cannot specify a column as an atomic counter and update the column in a single update request. For example, if you set Column A to an atomic counter, you cannot perform other operations such as overwrite and delete operations on the column at the same time.
You can perform multiple update operations on the same row by sending a BatchWriteRow request. However, if you perform an atomic counter operation on a row, you can perform only one update operation on the row in a BatchWriteRow request.
Only the value of the latest version of an atomic counter can be updated. You cannot update the value of a specified version of an atomic counter. After an update operation is complete, a new version of data is inserted into the atomic counter in the row.
API operations
The API operations that you can call to use the atomic counter feature are added to the updateRowChange class. The following table describes the operations.
Operation | Description |
IncrementColumn(columnName string, value int64) | Increases or decreases the value in a column by a number. |
AppendIncrementColumnToReturn(name string) | Specifies the name of the column whose value you want to return among the columns on which operations are performed to implement atomic counter. |
SetReturnIncrementValue() | Specifies a data type to return the value of an atomic counter. |
Parameters
Parameter | Required | Description |
TableName | Yes | The name of the data table. |
ColumnName | Yes | The name of the column on which you want to perform atomic counter operations. You can specify a column only of the INTEGER type. |
Value | Yes | The increment or decrement in the column value. |
Examples
The following sample code provides an example on how to call the updateRowChange operation to increase the value of a column of the INTEGER type when data is written and how to read the new values of the column:
func UpdateRowWithIncrement(client *tablestore.TableStoreClient, tableName string) {
fmt.Println("begin to update row")
updateRowRequest := new(tablestore.UpdateRowRequest)
updateRowChange := new(tablestore.UpdateRowChange)
// Specify the name of the data table.
updateRowChange.TableName = tableName
updatePk := new(tablestore.PrimaryKey)
updatePk.AddPrimaryKeyColumn("pk1", "pk1increment")
updatePk.AddPrimaryKeyColumn("pk2", int64(2))
updatePk.AddPrimaryKeyColumn("pk3", []byte("pk3"))
updateRowChange.PrimaryKey = updatePk
// Specify that the value of the col2 column on which operations are performed to implement atomic counter is increased by 30. Do not specify timestamps.
updateRowChange.IncrementColumn("col2", int64(30))
// Return the values of the column on which operations are performed to implement atomic counter.
updateRowChange.SetReturnIncrementValue()
updateRowChange.SetCondition(tablestore.RowExistenceExpectation_IGNORE)
updateRowChange.AppendIncrementColumnToReturn("col2")
updateRowRequest.UpdateRowChange = updateRowChange
resp, err := client.UpdateRow(updateRowRequest)
if err != nil {
fmt.Println("update failed with error:", err)
return
} else {
fmt.Println("update row finished")
fmt.Println(len(resp.Columns))
fmt.Println(resp.Columns[0].ColumnName)
fmt.Println(resp.Columns[0].Value)
fmt.Println(resp.Columns[0].Timestamp)
}
}