All Products
Search
Document Center

Tablestore:Perform conditional updates

Last Updated:Nov 30, 2023

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 a client.

  • 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 in a data table, you can specify row existence conditions and column-based conditions to perform conditional updates. The data in the data table is updated only if the conditions are met.

You can specify row existence conditions and column-based conditions for a conditional update.

  • Column-based condition

    Column-based conditions include SingleColumnValueConditions and CompositeColumnValueConditions, which are used to perform condition-based judgment based on the values of one or more columns. Column-based conditions are similar to the conditions that are used by Tablestore filters.

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

    • A SingleColumnValueCondition allows you to compare a column with a constant. A SingleColumnValueCondition does not support the comparison between two columns or two constants.

    • A CompositeColumnValueCondition consists of multiple SingleColumnValueConditions or CompositeColumnValueConditions. You must specify the logical relationships among the subconditions.

  • Row existence condition

    When you update a data table, Tablestore first checks whether row existence conditions are met. If the row existence conditions are not met, the update fails and an error is reported.

    The following row existence conditions are supported: IGNORE, EXPECT_EXIST, and EXPECT_NOT_EXIST.

Parameters

Parameter

Description

RowExistenceExpectation

When you update a data table, Tablestore first checks whether row existence conditions are met. If the row existence conditions are not met, the update fails and an error is reported.

The following row existence conditions are supported: IGNORE, EXPECT_EXIST, and EXPECT_NOT_EXIST.

  • IGNORE: The existence of the row is ignored. No row existence check is performed.

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

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

ColumnName

The name of the column.

ColumnValue

The value to be compared with the column.

CompareOperator

The relational operator that is used to compare values. For more information, see ComparatorType.

The following relational operators are supported: =, !=, >, >=, <, and <=.

LogicOperator

The logical operator that is used to combine multiple conditions. For more information, see LogicalOperator.

The following relational operators are supported: NOT, AND, and OR. The number of required subconditions varies based on logical operators.

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

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

PassIfMissing

Specifies whether to the conditional check is passed if a column does not exist in a row. The value of this parameter is of the Boolean data type. The default value is true, which indicates that if the column does not exist in a row, the conditional check is passed and the row meets the update conditions.

If the PassIfMissing parameter is set to false, the conditional check fails when the column does not exist in a row.

LatestVersionsOnly

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

If the LatestVersionsOnly parameter is set to false, the column values of all versions are used for comparison if the column has multiple versions of data. In this case, the conditional check is passed when one of the versions of values meets the condition.

Examples

The following examples show on how to update data based on column-based conditions and optimistic locking.

Update data based on column-based conditions

  • Construct a SinglleColumnValueCondition

    In the following example, the value of the Col0 column is updated if the value meets the condition of Col0==0.

    private static void updateRowWithSingleColumnValueCondition(SyncClient client, String pkValue){
        // Construct the primary key. 
        PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString(pkValue));
        PrimaryKey primaryKey = primaryKeyBuilder.build();
        
        // Read a row of data. 
        SingleRowQueryCriteria criteria = new SingleRowQueryCriteria("<TABLE_NAME>", primaryKey);
        criteria.setMaxVersions(1);
        GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
        Row row = getRowResponse.getRow();
        long col0Value = row.getLatestColumn("Col0").getValue().asLong();
    
        // Specify the name of the data table. 
        RowUpdateChange rowUpdateChange = new RowUpdateChange("<TABLE_NAME>", primaryKey);
    
        // Set the condition: Col0==0. 
        SingleColumnValueCondition singleColumnValueCondition = new SingleColumnValueCondition("Col0",
                SingleColumnValueCondition.CompareOperator.EQUAL, ColumnValue.fromLong(0));
        // If the Col0 column does not exist, the conditional check fails. 
        singleColumnValueCondition.setPassIfMissing(false);
        // Specify that only the latest version is used for comparison. 
        singleColumnValueCondition.setLatestVersionsOnly(true);
        Condition condition = new Condition();
        condition.setColumnCondition(singleColumnValueCondition);
        rowUpdateChange.setCondition(condition);
        // If the value of the Col0 column meets the column-based condition, the value of the Col0 column is increased by 1. 
        rowUpdateChange.put(new Column("Col0", ColumnValue.fromLong(col0Value+1)));
        try {
            client.updateRow(new UpdateRowRequest(rowUpdateChange));
            System.out.println("Data updated. ");
        } catch (TableStoreException ex) {
            System.out.println("Failed to update data. " + ex.toString());
        }
    }                 
  • Construct a CompositeColumnValueCondition

    In the following example, the value of the Col0 column is updated if the value meets one of the following conditions: Col0==0 AND Col1>100 and Col2<=10.

    private static void updateRowWithCompositeColumnValueCondition(SyncClient client, String pkValue){
        // Construct the primary key. 
        PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString(pkValue));
        PrimaryKey primaryKey = primaryKeyBuilder.build();
            
    		// Read a row of data. 
        SingleRowQueryCriteria criteria = new SingleRowQueryCriteria("<TABLE_NAME>", primaryKey);
        criteria.setMaxVersions(1);
        GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
        Row row = getRowResponse.getRow();
        long col0Value = row.getLatestColumn("Col0").getValue().asLong();
    
        // Specify the name of the data table. 
        RowUpdateChange rowUpdateChange = new RowUpdateChange("<TABLE_NAME>", primaryKey);
    
        // Set the composite1 condition to (Col0 == 0) AND (Col1 > 100). 
        CompositeColumnValueCondition composite1 = new CompositeColumnValueCondition(CompositeColumnValueCondition.LogicOperator.AND);
        SingleColumnValueCondition single1 = new SingleColumnValueCondition("Col0",
                SingleColumnValueCondition.CompareOperator.EQUAL, ColumnValue.fromLong(0));
        SingleColumnValueCondition single2 = new SingleColumnValueCondition("Col1",
                SingleColumnValueCondition.CompareOperator.GREATER_THAN, ColumnValue.fromLong(100));
        composite1.addCondition(single1);
        composite1.addCondition(single2);
    
        // Set the composite2 condition to ((Col0 == 0) AND (Col1 > 100)) OR (Col2 <= 10). 
        CompositeColumnValueCondition composite2 = new CompositeColumnValueCondition(CompositeColumnValueCondition.LogicOperator.OR);
        SingleColumnValueCondition single3 = new SingleColumnValueCondition("Col2",
                SingleColumnValueCondition.CompareOperator.LESS_EQUAL, ColumnValue.fromLong(10));
        composite2.addCondition(composite1);
        composite2.addCondition(single3);
    
        Condition condition = new Condition();
        condition.setColumnCondition(composite2);
        rowUpdateChange.setCondition(condition);
    		//  If the value of the Col0 column meets one of the column-based conditions, the value of the Col0 column is increased by 1. 
        rowUpdateChange.put(new Column("Col0", ColumnValue.fromLong(col0Value+1)));
        try {
            client.updateRow(new UpdateRowRequest(rowUpdateChange));
            System.out.println("Data updated. ");
        } catch (TableStoreException ex) {
            System.out.println("Failed to update data. " + ex.toString());
        }
    }

Update data based on optimistic locking

The following sample code provides an example on how to increase the value of a column based on optimistic locking.

In the following example, the value of the Col0 column is updated if the value that is read from the data table is the same as the current value of the Col0 column.

 private static void updateRowWithCondition(SyncClient client, String pkValue) {
     // Construct the primary key. 
     PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
     primaryKeyBuilder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString(pkValue));
     PrimaryKey primaryKey = primaryKeyBuilder.build();

     // Read a row of data. 
     SingleRowQueryCriteria criteria = new SingleRowQueryCriteria("<TABLE_NAME>", primaryKey);
     criteria.setMaxVersions(1);
     GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
     Row row = getRowResponse.getRow();
     long col0Value = row.getLatestColumn("Col0").getValue().asLong();

     // Configure conditional update to increase the value of the Col0 column by 1. 
     RowUpdateChange rowUpdateChange = new RowUpdateChange("<TABLE_NAME>", primaryKey);
     Condition condition = new Condition(RowExistenceExpectation.EXPECT_EXIST);
     ColumnCondition columnCondition = new SingleColumnValueCondition("Col0", SingleColumnValueCondition.CompareOperator.EQUAL, ColumnValue.fromLong(col0Value));
     condition.setColumnCondition(columnCondition);
     rowUpdateChange.setCondition(condition);
     rowUpdateChange.put(new Column("Col0", ColumnValue.fromLong(col0Value + 1)));

     try {
         client.updateRow(new UpdateRowRequest(rowUpdateChange));
     } catch (TableStoreException ex) {
         System.out.println(ex.toString());
     }
 }