If you use conditional update, data in the table can be updated only when the conditions are met. If the conditions are not met, the update fails.

Prerequisites

  • The OTSClient instance is initialized. For more information, see Initialization.
  • A data table is created. Data is written to the table.

Usage notes

When you use 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 when the conditions are met.

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

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

    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.

  • Column-based conditions include SingleColumnValueCondition and CompositeColumnValueCondition, which are used to determine whether the conditions are met based on the values of one or more columns. If the column-based condition is not met, the modification fails and an error is reported.
    • SingleColumnValueCondition supports the comparison between a constant and a column. SingleColumnValueCondition does not support the comparison between two columns or two constants.
    • The inner node of CompositeColumnValueCondition is used to perform logical operations. Subconditions can be SingleColumnValueCondition or CompositeColumnValueCondition.

Conditional update can be used to implement optimistic locking. When you update a row, the value of the specified column is obtained. Assume that Column A has a value of 1. Obtain the value in Column A and set a condition that the value in Column A is 1. Update the value in Column A to 2. If the row is updated by another client, the update fails.

Limits

Column-based conditions for conditional update support relational operators such as =, !=, >, >=, <, and <=, and logical operators such as NOT, AND, and OR. You can specify up to 10 conditions.

Parameters

You can use PutRow, UpdateRow, DeleteRow, and BatchWriteRow.for conditional update.

    'condition' => [
        'row_existence' => <RowExistenceExpectation>
        'column_condition' => <ColumnCondition>
    ]   

When only a row existence condition exists, it can be abbreviated:

    'condition' => <RowExistenceExpectation>    
  • The following code provides an example on how to construct SingleColumnValueCondition:
        [
            'column_name' => '<string>',
            'value' => <ColumnValue>,
            'comparator' => <ComparatorType>
            'pass_if_missing' => true || false
            'latest_version_only' => true || false
        ]
            
  • The following code provides an example on how to construct CompositeColumnValueFilter:
        [
            'logical_operator' => <LogicalOperator>
            'sub_conditions' => [
                <ColumnCondition>,
                <ColumnCondition>,
                <ColumnCondition>,
                // other conditions
            ]
        ]
            
ParameterDescription
row_existenceWhen you modify a table, the system 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, RowExistenceExpectationConst::CONST_IGNORE indicates IGNORE, RowExistenceExpectationConst::CONST_EXPECT_EXIST indicates EXPECT_EXIST, and RowExistenceExpectationConst::CONST_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. If the row does not exist, the condition is not met.
  • EXPECT_NOT_EXIST: Expect that the row does not exist. If the row does not exist, the condition is met. If the row exists, the condition is not met.
column_nameThe column name.
valueThe comparison value of the column.

The parameter value is in the format of [Value, Type]. Type can be set to ColumnTypeConst::CONST_INTEGER, ColumnTypeConst::CONST_STRING, ColumnTypeConst::CONST_BINARY, ColumnTypeConst::CONST_BOOLEAN, or ColumnTypeConst::CONST_DOUBLE, which respectively indicate the INTEGER, STRING (UTF-8 encoded string), BINARY, BOOLEAN, and DOUBLE types. If the type is BINARY, the type must be specified. Otherwise, the type can be ignored.

If the type is BINARY, you must set both the type and value.

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

Relational operators include EQUAL (=), NOT_EQUAL (!=), GREATER_THAN (>), GREATER_EQUAL (>=), LESS_THAN (<), and LESS_EQUAL (<=). In Tablestore, ComparatorTypeConst::CONST_EQUAL indicates EQUAL (=), ComparatorTypeConst::CONST_NOT_EQUAL indicates NOT_EQUAL (!=), ComparatorTypeConst::CONST_GREATER_THAN indicates GREATER_THAN (>), ComparatorTypeConst::CONST_GREATER_EQUAL indicates GREATER_EQUAL (>=), ComparatorTypeConst::CONST_LESS_THAN indicates LESS_THAN (<), and ComparatorTypeConst::CONST_LESS_EQUAL indicates LESS_EQUAL (<=).

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

Logical operators include NOT, AND, and OR. In Tablestore, LogicalOperatorConst::CONST_NOT indicates NOT, LogicalOperatorConst::CONST_AND indicates AND, and LogicalOperatorConst::CONST_OR indicates OR.

Different logical operators require different number of subconditions.
  • When the logical operator is NOT, only one subcondition can be added.
  • When the logical operator is AND or OR, you must add at least two subconditions.
pass_if_missingSpecifies whether to pass the conditional check when a column does not exist in a row. The type of this parameter value is Boolean. 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.

When pass_if_missing is set to false, if the column does not exist in a row, the conditional check fails, and the row does not meet the update conditions.

latest_version_onlySpecifies whether to use only the value of the latest version when the comparison value has multiple versions. The type of this parameter value is Boolean. 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.

When latest_version_only is set to false, the comparison values of all versions are used for comparison if the comparison value has multiple versions. In this case, if only the value of a version meets the condition, the conditional check is passed, and the row meets the update conditions.

Examples

  • The following code provides an example on how to construct SingleColumnValueCondition:
        // Set conditional update. If the value of Col0 is 0, the conditional check is passed.
        $column_condition = [
            'column_name' => 'Col0',
            'value' => 0,
            'comparator' => ComparatorTypeConst::CONST_EQUAL 
            'pass_if_missing' => false                         // If a row does not contain the Col0 column, the conditional check fails.
            'latest_version_only' => true                      // Specify that only the latest version is used for comparison.
        ];
            
  • The following code provides an example on how to construct CompositeColumnValueCondition:
    // Set condition composite1 to (Col0 == 0) AND (Col1 > 100).
        $composite1 = [
            'logical_operator' => LogicalOperatorConst::CONST_AND,
            'sub_conditions' => [
                [
                    'column_name' => 'Col0',
                    'value' => 0,
                    'comparator' => ComparatorTypeConst::CONST_EQUAL
                ],
                [
                    'column_name' => 'Col1',
                    'value' => 100,
                    'comparator' => ComparatorTypeConst::CONST_GREATER_THAN
                ]
            ]
        ];
        // Set condition composite2 to ( (Col0 == 0) AND (Col1 > 100) ) OR (Col2 <= 10).
        $composite2 = [
            'logical_operator' => LogicalOperatorConst::CONST_OR,
            'sub_conditions' => [
                $composite1,
                [
                    'column_name' => 'Col2',
                    'value' => 10,
                    'comparator' => ComparatorTypeConst::CONST_LESS_EQUAL
                ]
            ]
        ];
  • The following code provides an example on how to implement optimistic locking by increasing the value of a column:
        // Read a row of data.
        $request = [
            'table_name' => 'MyTable',
            'primary_key' => [ // The primary key.
                ['PK0', 123],
                ['PK1', 'abc']
            ],
            'max_versions' => 1
        ];
        $response = $otsClient->getRow ($request);
        $columnMap = getColumnValueAsMap($response['attribute_columns']);
        $col0Value = $columnMap['col0'][0][1];
        // Configure conditional update for Col0 to increase the value of Col0 by 1.
        $request = [
            'table_name' => 'MyTable',
            'condition' => [
                'row_existence' => RowExistenceExpectationConst::CONST_EXPECT_EXIST,
                'column_condition' => [                  // If the condition is met, the data is updated.
                    'column_name' => 'col0',
                    'value' => $col0Value,
                    'comparator' => ComparatorTypeConst::CONST_EQUAL
                ]
            ],
            'primary_key' => [ // The primary key.
                ['PK0', 123],
                ['PK1', 'abc']
            ],
            'update_of_attribute_columns'=> [
                'PUT' => [
                    ['col0', $col0Value+1]
                ]
            ]
        ];
        $response = $otsClient->updateRow ($request);