All Products
Search
Document Center

Tablestore:Conditional updates

Last Updated:Sep 20, 2026

You can update data in a data table only when the data meets the column condition. If the data does not meet the column condition, the update fails.

Prerequisites

Description

The Condition container holds a row existence condition (rowExistenceExpectation), a column condition (columnCondition), or both. Pass the configured condition to setCondition() on RowPutChange, RowUpdateChange, or RowDeleteChange. These row changes can also be included in a BatchWriteRow request. If the condition is not met, the server returns an error and the row remains unchanged.

rowChange.setCondition(condition)
new SingleColumnValueCondition(columnName, operator, columnValue)
new CompositeColumnValueCondition(logicOperator)

The following example updates the row with primary key row1 in the condition_demo table only when the row exists. Otherwise, the server returns an error.

PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
        .addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"))
        .build();

RowUpdateChange rowUpdateChange = new RowUpdateChange("condition_demo", primaryKey);
rowUpdateChange.put("col1", ColumnValue.fromString("changed_val1"));

Condition condition = new Condition();
condition.setRowExistenceExpectation(RowExistenceExpectation.EXPECT_EXIST);
rowUpdateChange.setCondition(condition);

client.updateRow(new UpdateRowRequest(rowUpdateChange));

Parameters

Conditional updates can be used as a condition for PutRow, UpdateRow, DeleteRow, and BatchWriteRow operations.

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

If only a row existence condition is specified, you can use the following shorthand structure.

    'condition' => <RowExistenceExpectation>    

The structures for SingleColumnValueCondition and CompositeColumnValueCondition are as follows.

SingleColumnValueCondition structure

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

CompositeColumnValueFilter structure

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

Parameter

Description

row_existence

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

The row existence conditions include IGNORE, EXPECT_EXIST, and EXPECT_NOT_EXIST. They are represented by RowExistenceExpectationConst::CONST_IGNORE, RowExistenceExpectationConst::CONST_EXPECT_EXIST, and RowExistenceExpectationConst::CONST_EXPECT_NOT_EXIST.

  • IGNORE: Ignores the check. No existence check is performed.

  • EXPECT_EXIST: Expects the row to exist. The condition is met if the row exists. The condition is not met if the row does not exist.

  • EXPECT_NOT_EXIST: Expects the row to not exist. The condition is met if the row does not exist. The condition is not met if the row exists.

column_name

The name of the column.

value

The value to compare the column against.

The format is [Value, Type]. Type can be INTEGER, STRING (UTF-8 encoded), BINARY, BOOLEAN, or DOUBLE. These are represented by ColumnTypeConst::CONST_INTEGER, ColumnTypeConst::CONST_STRING, ColumnTypeConst::CONST_BINARY, ColumnTypeConst::CONST_BOOLEAN, and ColumnTypeConst::CONST_DOUBLE. The type for BINARY is required. The types for other values are optional.

If the type is not BINARY, you can use the shorthand format Value.

comparator

The relational operator used to compare the column value. For more information about the type, see ComparatorType.

The relational operators include EQUAL (=), NOT_EQUAL (!=), GREATER_THAN (>), GREATER_EQUAL (>=), LESS_THAN (<), and LESS_EQUAL (<=). They are represented by ComparatorTypeConst::CONST_EQUAL, ComparatorTypeConst::CONST_NOT_EQUAL, ComparatorTypeConst::CONST_GREATER_THAN, ComparatorTypeConst::CONST_GREATER_EQUAL, ComparatorTypeConst::CONST_LESS_THAN, and ComparatorTypeConst::CONST_LESS_EQUAL.

logical_operator

The logical operator used to combine multiple conditions. For more information about the type, see LogicalOperator.

The logical operators include NOT, AND, and OR. They are represented by LogicalOperatorConst::CONST_NOT, LogicalOperatorConst::CONST_AND, and LogicalOperatorConst::CONST_OR.

The number of sub-conditions you can add depends on the logical operator.

  • If the logical operator is NOT, you can add only one sub-condition.

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

pass_if_missing

Specifies whether the condition check passes if the column does not exist in a row. The type is boolean. The default value is true. This means if the column does not exist in a row, the condition check passes and the row meets the update condition.

If you set pass_if_missing to false, the condition check fails if the column does not exist in a row. The row does not meet the update condition.

latest_version_only

Specifies whether to use only the latest version of the column value for comparison if the column has multiple versions. The type is boolean. The default value is true. This means if the column has multiple versions, only the latest version is used for comparison.

If you set latest_version_only to false and the column has multiple versions, all versions of the column value are used for comparison. In this case, if any version meets the condition, the condition check passes and the row meets the update condition.

Examples

Perform data operations based on row existence conditions

The following example shows how to perform an operation on a row based on its primary key and a specified row existence condition.

$request = array (
    'tables' => array (
        array (
            'table_name' => 'my_table',
            'rows' => array (  
                array (
                    // PUT operation
                    'operation_type' => OperationTypeConst::CONST_PUT,
                    // Expects the row to not exist. The condition is met if the row does not exist.
                    '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,
                    // Expects the row to exist. The condition is met if the row exists.
                    '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, 
                    // Ignore. No existence check is performed.
                    'condition' => RowExistenceExpectationConst::CONST_IGNORE,
                    'primary_key' => array (
                        array('PK1', 'PrimaryKey'),
                        array('PK2', 33),
                    )
                ),
            )
        )
    )
);

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

// Process the response for each table
foreach ($response['tables'] as $tableData) {
    print "Handling table {$tableData['table_name']} ...\n";
    
    // Process the PutRow results for this table
    $putRows = $tableData['rows'];
    
    foreach ($putRows as $rowData) {
      
      if ($rowData['is_ok']) {
        // The write operation is successful
        print "Capacity Unit Consumed: {$rowData['consumed']['capacity_unit']['write']}\n";
      } else {
        // An error occurred
        print "Error: {$rowData['error']['code']} {$rowData['error']['message']}\n";
      }
    }
  }

Perform data operations based on row and column conditions

The following example shows how to perform an operation based on row and column conditions.

$request = array (
    'tables' => array (
        array (
            'table_name' => 'MyTable',
            'rows' => array (  
                // SingleColumnValueCondition structure
                  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 columns to update or append.
                    'update_of_attribute_columns'=> array(
                        'PUT' => array (
                            array('attr1', 'OTS'),
                            array('attr2',  128)
                        )
                    )
                ),

                // CompositeColumnValueFilter structure
                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 columns to delete.
                        'DELETE_ALL' => array(
                            'attr1',
                            'attr2'
                        )
                    )
                ),
            )
        )
    )
);

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

// Process the response for each table
foreach ($response['tables'] as $tableData) {
    print "Handling table {$tableData['table_name']} ...\n";
    
    // Process the PutRow results for this table
    $putRows = $tableData['rows'];
    
    foreach ($putRows as $rowData) {
      
      if ($rowData['is_ok']) {
        // The write operation is successful
        print "Capacity Unit Consumed: {$rowData['consumed']['capacity_unit']['write']}\n";
      } else {
        // An error occurred
        print "Error: {$rowData['error']['code']} {$rowData['error']['message']}\n";
      }
    }
  }

Use a condition to implement optimistic locking and increment a column

The following example shows how to create a condition to implement optimistic locking and increment a column.

    // Read a row of data.
    $request = [
        'table_name' => 'MyTable', 
        'primary_key' => [ // Primary key.
            ['PK0', 123],
            ['PK1', 'abc']
        ],
        'max_versions' => 1
    ];
    $response = $otsClient->getRow ($request);
    $columnMap = getColumnValueAsMap($response['attribute_columns']);
    $col0Value = $columnMap['col0'][0][1];
    // Conditionally update the col0 column to increment its value by 1.
    $request = [
        'table_name' => 'MyTable',
        'condition' => [
            'row_existence' => RowExistenceExpectationConst::CONST_EXPECT_EXIST,
            'column_condition' => [                  // If the condition is met, update the data.
                'column_name' => 'col0',
                'value' => $col0Value,
                'comparator' => ComparatorTypeConst::CONST_EQUAL
            ]
        ],
        'primary_key' => [ // Primary key.
            ['PK0', 123],
            ['PK1', 'abc']
        ],
        'update_of_attribute_columns'=> [
            'PUT' => [
                ['col0', $col0Value+1]
            ]
        ]
    ];
    $response = $otsClient->updateRow ($request);

For more code examples, see PutRow@GitHub, UpdateRow@GitHub, DeleteRow@GitHub, and BatchWriteRow@GitHub.