Atomic counters allow you to implement an atomic counter on a column. This feature provides statistic data for online applications such as the number of page views (PVs) on various topics.
Atomic counters reduce the write performance overhead caused by forced consistency. When you send a request to the server to perform read, modify, and write (RMW) operations, the server performs the operations on a row by locking the row. To ensure data consistency, you can update atomic counters on a database server to improve write performance.
Scenarios
You can use an atomic counter to keep track of a row in real time.
- When you use UpdateRow to add metadata of a picture to a row, the atomic counter is increased by one.
- When you use UpdateRow to delete metadata of a picture from a row, the atomic counter is decreased by one.
- You can use GetRow to read the value of the atomic counter to check the number of pictures whose metadata is stored in the row.
This function ensures database consistency. When you add metadata of a picture to a row, the atomic counter value of the row is increased by one instead of decreased by one.
Limits
- You can implement atomic counters only on INTEGER columns.
- By default, if a column that is specified as an atomic counter does not exist, the value of the column is 0 before you write data. 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 increased value of an atomic counter is returned.
- You cannot specify a column as an atomic counter and update the column in a single request. If Attribute Column A is set to an atomic counter, you cannot perform other operations such as overwrite and delete operations on the attribute column A.
- You can perform multiple update operations on the same row by using 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 is increased. You cannot increase the value of a specified version of an atomic counter. After you update a row, a new version of data is inserted to the atomic counter in the row.
API operations
The following table describes the operations added to the rowUpdateChange class to perform atomic counters.
API operation | Description |
---|---|
RowUpdateChange increment(Column column) | Increments or decreases the value in a column by a number. |
void addReturnColumn(String columnName) | Specifies the name of the atomic counter to return its value. |
void setReturnType(ReturnType returnType) | Specifies a data type to return the value of an atomic counter. |
Usage
You can use the following Tablestore SDKs to implement atomic counters:
- Tablestore SDK for Java: Atomic counters
- Tablestore SDK for Go: Atomic counters
- Tablestore SDK for Python: Atomic counters
- Tablestore SDK for Node.js: Atomic counters
- Tablestore SDK for .NET SDK: Atomic counters
Parameters
Parameter | Description |
---|---|
tableName | The name of the table. |
columnName | The name of the column you set to an atomic counter. You can specify only INTEGER columns as atomic counters. |
value | The value you increase to or decrease from the atomic counter value. |
returnType | If you set this parameter to ReturnType.RT_AFTER_MODIFY, the value of the atomic counter is returned. |
Examples
private static void incrementByUpdateRowApi(SyncClient client) {
// Specify the primary key.
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString("pk0"));
PrimaryKey primaryKey = primaryKeyBuilder.build();
// Specify the table.
RowUpdateChange rowUpdateChange = new RowUpdateChange(TABLE_NAME, primaryKey);
// Set the price column as an atomic counter and increase the value of the atomic counter by 10. You cannot specify the timestamp.
rowUpdateChange.increment(new Column("price", ColumnValue.fromLong(10)));
// Set the data type of the value to return to ReturnType.RT_AFTER_MODIFY and return the value of the atomic counter.
rowUpdateChange.addReturnColumn("price");
rowUpdateChange.setReturnType(ReturnType.RT_AFTER_MODIFY);
// Initiate a request to update the row.
UpdateRowResponse response = client.updateRow(new UpdateRowRequest(rowUpdateChange));
// Display the updated values.
Row row = response.getRow();
System.out.println(row);
}
Billing methods
The implementation of atomic counters does not affect the existing billing methods.