All Products
Search
Document Center

Tablestore:Conditional update

Last Updated:Apr 11, 2024

You can use the conditional update feature to update data in a data table only if the specified conditions are met. If the conditions are not met, the update fails.

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

When you call the PutRow, UpdateRow, DeleteRow, or BatchWriteRow operation to update data, you can use conditional update to check row existence conditions and column-based conditions. The update is successful only if the conditions are met.

Conditional update can be performed based on row existence conditions and column-based conditions.

  • Row existence conditions include IGNORE, EXPECT_EXIST, and EXPECT_NOT_EXIST.

    When you modify a data table, Tablestore first checks the row existence condition. If the row existence condition is not met, the modification fails and an error is reported.

  • Column-based conditions include SingleColumnCondition and CompositeCondition, which are used to determine whether the conditions are met based on the values of one or more columns.

    Column-based conditions support the following relational operators: =, !=, >, >=, <, and <=. Column-based conditions also support the following logical operators: NOT, AND, and OR. You can specify up to 10 column-based conditions for a conditional update.

    • SingleColumnCondition supports comparison between a constant and a column. The column can be a primary key column. SingleColumnCondition does not support comparison between two columns and two constants.

    • Logical operators are used to combine subconditions in CompositeCondition. The subconditions can be SingleColumnCondition or CompositeCondition.

You can use conditional update to perform optimistic locking. When you update a row, you must obtain the value of a specific column and specify a row update condition based on the column value. For example, when you update the value of Column A in a row to 2, you must obtain the value of Column A. In this example, the obtained value is 1. Then, you must specify that the row can be updated only if the value of Column A is 1. If the specified condition is met, the update is successful. If the row is updated by another client, the update fails.

Parameters

Parameter

Description

RowExistenceExpectation

The row existence condition. When you modify a table, Tablestore first checks the row existence condition. If the row existence condition is not met, the modification fails and an error is reported.

Row existence conditions include IGNORE, EXPECT_EXIST, and EXPECT_NOT_EXIST. In Tablestore, RowExistenceExpectation_IGNORE indicates IGNORE, RowExistenceExpectation_EXPECT_EXIST indicates EXPECT_EXIST, and RowExistenceExpectation_EXPECT_NOT_EXIST indicates EXPECT_NOT_EXIST.

  • IGNORE: No existence check is performed.

  • EXPECT_EXIST: The row is expected to exist. If the row exists, the condition is met. Otherwise, the condition is not met.

  • EXPECT_NOT_EXIST: The row is expected to not exist. If the row does not exist, the condition is met. Otherwise, the condition is not met.

ColumnName

The name of the column.

ColumnValue

The comparison value of the column.

Comparator

The relational operator used to compare the column value. For information about the types of relational operators, see ComparatorType.

Relational operators include EQUAL(=), NOT_EQUAL(!=), GREATER_THAN(>), GREATER_EQUAL(>=), LESS_THAN(<), and LESS_EQUAL(<=). In Tablestore, CT_EQUAL indicates EQUAL(=), CT_NOT_EQUAL indicates NOT_EQUAL(!=), CT_GREATER_THAN indicates GREATER_THAN(>), CT_GREATER_EQUAL indicates GREATER_EQUAL(>=), CT_LESS_THAN indicates LESS_THAN(<), and CT_LESS_EQUAL indicates LESS_EQUAL(<=).

Operator

The logical operator used to combine multiple conditions. For information about the types of logical operators, see LogicalOperator.

Logical operators include NOT, AND, and OR. In Tablestore, LO_NOT indicates NOT, LO_AND indicates AND, and LO_OR indicates OR.

The number of subconditions that you can specify varies based on the logical operator that you use.

  • If the logical operator is NOT, you can specify only one subcondition.

  • If the logical operator is AND or OR, you must specify at least two subconditions.

FilterIfMissing

Specifies whether to pass the condition check when a column does not exist in a row. The value of this parameter is of the Boolean type. The default value is false, which specifies that if the column does not exist in a row, the condition check is passed and the row meets the update conditions.

If you set the FilterIfMissing parameter to true and the column does not exist in a row, the condition check fails and the row does not meet the update conditions.

LatestVersionsOnly

Specifies whether to use only the latest version of value for comparison when a column has multiple versions of values. The value of this parameter is of the Boolean type. The default value is true, which specifies that if the column has multiple versions of values, only the latest version of value is used for comparison.

If you set the LatestVersionsOnly parameter to false and the column has multiple versions of values, all versions of values are used for comparison. In this case, if only one version meets the condition, the condition check is passed and the row meets the update conditions.

Examples

Update data by using row existence conditions

The following sample code provides an example on how to update a row based on the primary key. If the specified row exists, the update is successful. Otherwise, the update fails.

updateRowRequest := new(tablestore.UpdateRowRequest)
updateRowChange := new(tablestore.UpdateRowChange)
updateRowChange.TableName = tableName
updatePk := new(tablestore.PrimaryKey)
updatePk.AddPrimaryKeyColumn("pk1", "pk1value1")
updatePk.AddPrimaryKeyColumn("pk2", int64(2))
updatePk.AddPrimaryKeyColumn("pk3", []byte("pk3"))
updateRowChange.PrimaryKey = updatePk
updateRowChange.DeleteColumn("col1")            // Delete the col1 column. 
updateRowChange.PutColumn("col2", int64(77))    // Add the col2 column whose value is 77. 
updateRowChange.PutColumn("col4", "newcol3")    // Add the col4 column whose value is "newcol3". 
// Specify that the row is expected to exist. 
updateRowChange.SetCondition(tablestore.RowExistenceExpectation_EXPECT_EXIST)
updateRowRequest.UpdateRowChange = updateRowChange
_, err := client.UpdateRow(updateRowRequest)
if err != nil {
    fmt.Println("update failed with error:", err)
} else {
    fmt.Println("update row finished")
}

Update data by using row existence conditions and column-based conditions

  • Update a row by using conditions

    updateRowRequest := new(tablestore.UpdateRowRequest)
    updateRowChange := new(tablestore.UpdateRowChange)
    updateRowChange.TableName = tableName
    updatePk := new(tablestore.PrimaryKey)
    updatePk.AddPrimaryKeyColumn("pk1", "pk1value1")
    updateRowChange.PrimaryKey = updatePk
    updateRowChange.PutColumn("col2", int64(77)) // Add the col2 column whose value is 77. 
    // Specify that the expected value of the col5 column is 3. 
    clCondition1 := tablestore.NewSingleColumnCondition("col5", tablestore.CT_EQUAL, int64(3))
    // The default value of the FilterIfMissing parameter is false, which specifies that if the column does not exist in a row, the condition check is passed. 
    // If you want to specify that the condition check fails if the column does not exist in a row, set the FilterIfMissing parameter to true. 
    //clCondition1.FilterIfMissing = true
    // Specify that the row is expected to exist. 
    updateRowChange.SetCondition(tablestore.RowExistenceExpectation_EXPECT_EXIST)
    updateRowChange.SetColumnCondition(clCondition1)
    updateRowRequest.UpdateRowChange = updateRowChange
    _, err := client.UpdateRow(updateRowRequest)
    if err != nil {
        fmt.Println("update failed with error:", err)
    } else {
        fmt.Println("update row finished")
    }

  • Delete a row by using conditions

    The following sample code provides an example on how to delete a row based on the primary key. If the specified row exists and the value of the col2 column is 3, the update is successful. Otherwise, the update fails.

    deleteRowReq := new(tablestore.DeleteRowRequest)
    deleteRowReq.DeleteRowChange = new(tablestore.DeleteRowChange)
    deleteRowReq.DeleteRowChange.TableName = tableName
    deletePk := new(tablestore.PrimaryKey)
    deletePk.AddPrimaryKeyColumn("pk1", "pk1value1")
    deletePk.AddPrimaryKeyColumn("pk2", int64(2))
    deletePk.AddPrimaryKeyColumn("pk3", []byte("pk3"))
    deleteRowReq.DeleteRowChange.PrimaryKey = deletePk
    
    // Specify that the row is expected to exist. 
    deleteRowReq.DeleteRowChange.SetCondition(tablestore.RowExistenceExpectation_EXPECT_EXIST)
    // Specify that the expected value of the col2 column is 3. 
    clCondition1 := tablestore.NewSingleColumnCondition("col2", tablestore.CT_EQUAL, int64(3))
    // The default value of the FilterIfMissing parameter is false, which specifies that if the column does not exist in a row, the condition check is passed. 
    // If you want to specify that the condition check fails if the column does not exist in a row, set the FilterIfMissing parameter to true. 
    //clCondition1.FilterIfMissing = true
    deleteRowReq.DeleteRowChange.SetColumnCondition(clCondition1)
    _, err := client.DeleteRow(deleteRowReq)
    if err != nil {
        fmt.Println("delete failed with error:", err)
    } else {
        fmt.Println("delete row finished")
    }