如果要在某些在线应用中快速进行计数操作,您可以使用原子计数器实现。使用原子计数器时,您需要将表中的某一列当成一个原子计数器,然后对该列进行原子计数操作。
前提条件
已初始化Client。具体操作,请参见初始化OTSClient。
已创建数据表并写入数据。
注意事项
只支持对整型列的列值进行原子计数操作。
作为原子计数器的列,如果写入数据前该列不存在,则默认值为0;如果写入数据前该列已存在且列值非整型,则产生OTSParameterInvalid错误。
增量值可以是正数或负数,但不能出现计算溢出。如果出现计算溢出,则产生OTSParameterInvalid错误。
默认不返回进行原子计数操作的列值,您可以通过相应操作指定返回进行原子计数操作的列值。
在单次更新请求中,不能对某一列同时进行更新和原子计数操作。假设列A已经执行原子计数操作,则列A不能再执行其他操作(例如列的覆盖写,列删除等)。
在一次BatchWriteRow请求中,支持对同一行数据进行多次更新操作。但是如果某一行已进行原子计数操作,则该行在此批量请求中只能出现一次。
原子计数操作只能作用在列值的最新版本,不支持对列值的特定版本做原子计数操作。更新完成后,原子计数操作会插入一个新的数据版本。
接口
updateRowChange类中新增了原子计数器的操作接口,操作接口说明请参见下表。
接口 | 说明 |
IncrementColumn(columnName string, value int64) | 对列执行增量变更,例如+X,-X等。 |
AppendIncrementColumnToReturn(name string) | 对于进行原子计数操作的列,设置需要返回列值的列名。 |
SetReturnIncrementValue() | 设置返回类型,返回进行原子计数操作的列的新值。 |
参数
参数 | 是否必选 | 说明 |
TableName | 是 | 数据表名称。 |
ColumnName | 是 | 进行原子计数操作的列名。只支持对整型列的列值进行原子计数器操作。 |
Value | 是 | 对列进行增量变更的值。 |
示例
以下示例用于在写入数据时使用updateRowChange接口对整型列做列值的增量变更,然后读取更新后的新值。
func UpdateRowWithIncrement(client *tablestore.TableStoreClient, tableName string) {
fmt.Println("begin to update row")
updateRowRequest := new(tablestore.UpdateRowRequest)
updateRowChange := new(tablestore.UpdateRowChange)
//设置数据表名称。
updateRowChange.TableName = tableName
updatePk := new(tablestore.PrimaryKey)
updatePk.AddPrimaryKeyColumn("pk1", "pk1increment")
updatePk.AddPrimaryKeyColumn("pk2", int64(2))
updatePk.AddPrimaryKeyColumn("pk3", []byte("pk3"))
updateRowChange.PrimaryKey = updatePk
//将进行原子计数操作的col2列的列值+30,不能设置时间戳。
updateRowChange.IncrementColumn("col2", int64(30))
//将进行原子计数操作的列值返回。
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)
}
}