All Products
Search
Document Center

Tablestore:Perform conditional update

Last Updated:Sep 14, 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

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

You can configure the condition parameter when you use the PutRow, UpdateRow, DeleteRow, or BatchWriteRow operation to perform conditional update.

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

When only a row existence condition exists, the condition can be abbreviated. The following sample code shows the abbreviation:

    'condition' => <RowExistenceExpectation>    

The following sample code shows how to construct SingleColumnValueCondition and CompositeColumnValueFilter:

SingleColumnValueCondition

    [
        'column_name' => '<string>',
        'value' => <ColumnValue>,
        'comparator' => <ComparatorType>,
        'pass_if_missing' => true || false,
        'latest_version_only' => true || false
    ]

CompositeColumnValueFilter

    [
        'logical_operator' => <LogicalOperator>
        'sub_conditions' => [
            <ColumnCondition>,
            <ColumnCondition>,
            <ColumnCondition>,
            // other conditions
        ]
    ]

Parameter

Description

row_existence

The row existence condition. When you modify a data table, Tablestore 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 specifies IGNORE, RowExistenceExpectationConst::CONST_EXPECT_EXIST specifies EXPECT_EXIST, and RowExistenceExpectationConst::CONST_EXPECT_NOT_EXIST specifies EXPECT_NOT_EXIST.

  • IGNORE: No row 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: The row is expected not to exist. If the row does not exist, the condition is met. If the row exists, the condition is not met.

column_name

The name of the column.

value

The comparison value of the column.

The value of this parameter is in the [Value, Type] format. You can specify Integer, String, Binary, Boolean, or Double as the type. In Tablestore, ColumnTypeConst::CONST_INTEGER specifies an Integer value, ColumnTypeConst::CONST_STRING specifies a UTF-8 encoded string, ColumnTypeConst::CONST_BINARY specifies a Binary value, ColumnTypeConst::CONST_BOOLEAN specifies a Boolean value, and ColumnTypeConst::CONST_DOUBLE specifies a Double value. If the type is Binary, you must specify the value and the type.

If the type is not Binary, you can specify the value without specifying the type.

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, ComparatorTypeConst::CONST_EQUAL specifies EQUAL(=), ComparatorTypeConst::CONST_NOT_EQUAL specifies NOT_EQUAL(!=), ComparatorTypeConst::CONST_GREATER_THAN specifies GREATER_THAN(>), ComparatorTypeConst::CONST_GREATER_EQUAL specifies GREATER_EQUAL(>=), ComparatorTypeConst::CONST_LESS_THAN specifies LESS_THAN(<), and ComparatorTypeConst::CONST_LESS_EQUAL specifies LESS_EQUAL(<=).

logical_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, LogicalOperatorConst::CONST_NOT specifies NOT, LogicalOperatorConst::CONST_AND specifies AND, and LogicalOperatorConst::CONST_OR specifies 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.

pass_if_missing

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 true, 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 pass_if_missing parameter to false and the column does not exist in a row, the condition check fails and the row does not meet the update conditions.

latest_version_only

Specifies whether to use only the latest version of data for comparison when a column has multiple versions of data. 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 data, only the latest version of data is used for comparison.

If you set the latest_version_only parameter to false and the column has multiple versions of data, all versions of data 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

Perform operations on data based on a row existence condition

The following sample code provides an example on how to perform operations on a row of data based on the primary key of the row. In this example, if the specified row exists, the operations succeed. Otherwise, the operations fail.

$request = array (
    'tables' => array (
        array (
            'table_name' => '<My_Table>',
            'rows' => array (  
                array (
                    // PUT operation
                    'operation_type' => OperationTypeConst::CONST_PUT,
                    // The specified row is expected not to exist. If the specified row does not exist, the condition is met. 
                    'condition' => RowExistenceExpectationConst::CONST_EXPECT_NOT_EXIST,
                    'primary_key' => array (
                        array('PK1', 'PrimaryKey'),
                        array('PK2', 11),
                    ),
                    'attribute_columns' => array (
                        array('attr1', 'Tablestore'),
                        array('attr2', 128)
                    )
                ),

                array (
                    // UPDATE operation
                    'operation_type' => OperationTypeConst::CONST_UPDATE,
                    // The specified row is expected to exist. If the specified row exists, the condition is met. 
                    'condition' => RowExistenceExpectationConst::CONST_EXPECT_EXIST,
                    'primary_key' => array (
                        array('PK1', 'PrimaryKey'),
                        array('PK2', 22),
                    ),
                    'update_of_attribute_columns'=> array(
                        'PUT' => array (
                            array('attr1', 'OTS'),
                            array('attr2',  256)
                        )
                    )
                ),
                
                array (
                    // DELETE operation
                    'operation_type' => OperationTypeConst::CONST_DELETE, 
                    // No row existence check is performed. 
                    'condition' => RowExistenceExpectationConst::CONST_IGNORE,
                    'primary_key' => array (
                        array('PK1', 'PrimaryKey'),
                        array('PK2', 33),
                    )
                ),
            )
        )
    )
);

$response = $otsClient->batchWriteRow ($request);

// Process each table that is returned.
foreach ($response['tables'] as $tableData) {
    print "Handling table {$tableData['table_name']} ...\n";
    
    // Process the result returned by the PutRow operation in this table.
    $putRows = $tableData['rows'];
    
    foreach ($putRows as $rowData) {
      
      if ($rowData['is_ok']) {
        // Data is written.
        print "Capacity Unit Consumed: {$rowData['consumed']['capacity_unit']['write']}\n";
      } else {
        // Display the error information.
        print "Error: {$rowData['error']['code']} {$rowData['error']['message']}\n";
      }
    }
  }

Perform operations on data based on row existence conditions and conditions based on column values

The following sample code provides an example on how to perform operations on data based on row existence conditions and conditions based on column values:

$request = array (
    'tables' => array (
        array (
            'table_name' => 'MyTable',
            'rows' => array (  
                // Construct SingleColumnValueCondition.
                  array (
                    // UPDATE operation
                    'operation_type' => OperationTypeConst::CONST_UPDATE,
                    'condition' => array (
                        'row_existence' => RowExistenceExpectationConst::CONST_EXPECT_EXIST,
                        //attr2 != 256
                        'column_condition' => array (
                            'column_name' => 'attr2',
                            'value' => 256,
                            'comparator' => ComparatorTypeConst::CONST_NOT_EQUAL
                        )
                    ),
                    'primary_key' => array (
                        array('PK1', 'PrimaryKey'),
                        array('PK2', 11)
                    ),
                    // Use attribute_columns/put to specify the column that you want to update or add.
                    'update_of_attribute_columns'=> array(
                        'PUT' => array (
                            array('attr1', 'OTS'),
                            array('attr2',  128)
                        )
                    )
                ),

                // Construct CompositeColumnValueFilter.
                array ( 
                    // UPDATE operation
                    'operation_type' => OperationTypeConst::CONST_UPDATE,
                    'condition' => array (
                        'row_existence' => RowExistenceExpectationConst::CONST_EXPECT_EXIST,
                        // attr1 = 'Tablestore' and attr2 >= 256
                        'column_condition' => array (
                            'logical_operator' => LogicalOperatorConst::CONST_AND,
                            'sub_conditions' => array (
                                array (
                                    'column_name' => 'attr2',
                                    'value' => 256,
                                    'comparator' => ComparatorTypeConst::CONST_GREATER_EQUAL
                                ),
                                array (
                                    'column_name' => 'attr1',
                                    'value' => 'Tablestore',
                                    'comparator' => ComparatorTypeConst::CONST_EQUAL
                                )
                            )
                        )
                    ),
                    'primary_key' => array (
                        array('PK1', 'pkValue'),
                        array('PK2', 22)
                    ),
                    'update_of_attribute_columns'=> array(
                        'PUT' => array (),
                        // Use attribute_columns/delete to specify the column that you want to delete.
                        'DELETE_ALL' => array(
                            'attr1',
                            'attr2'
                        )
                    )
                ),
            )
        )
    )
);

$response = $otsClient->batchWriteRow ($request);

// Process each table that is returned.
foreach ($response['tables'] as $tableData) {
    print "Handling table {$tableData['table_name']} ...\n";
    
    // Process the result returned by the PutRow operation in this table.
    $putRows = $tableData['rows'];
    
    foreach ($putRows as $rowData) {
      
      if ($rowData['is_ok']) {
        // Data is written.
        print "Capacity Unit Consumed: {$rowData['consumed']['capacity_unit']['write']}\n";
      } else {
        // Display the error information.
        print "Error: {$rowData['error']['code']} {$rowData['error']['message']}\n";
      }
    }
  }

Construct a condition to perform optimistic locking to increase the value of a column

The following sample code provides an example on how to construct a condition to perform optimistic locking to increase 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 the Col0 column to increase the value of the Col0 column 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);

For more sample code, visit, PutRow@GitHub, UpdateRow@GitHub, DeleteRow@GitHub, and BatchWriteRow@GitHub.