The Tablestore SDK for Java writes, updates, or deletes a row only when the target row meets the specified condition.
Prerequisites
Install Tablestore SDK for Java and initialize a client.
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
Update condition
Condition contains the following parameters. The row existence condition and column condition can be used separately or together. No condition is evaluated when rowExistenceExpectation is IGNORE and columnCondition is not set.
|
Name |
Type |
Description |
|
rowExistenceExpectation (optional) |
RowExistenceExpectation |
The row existence condition. Valid values:
|
|
columnCondition (optional) |
ColumnCondition |
The column condition. The subclasses are |
Single-column value condition
When Condition.columnCondition is a SingleColumnValueCondition, it contains the following parameters.
|
Name |
Type |
Description |
|
columnName (required) |
String |
The name of the attribute column to check. |
|
operator (required) |
CompareOperator |
The comparison operator. Valid values:
|
|
columnValue (required) |
ColumnValue |
The value to compare against. |
|
passIfMissing (optional) |
boolean |
Whether to treat the row as meeting the condition when the target attribute column is missing. Default: Set to |
|
latestVersionsOnly (optional) |
boolean |
Whether to check only the latest data version. Default: Set to |
Composite condition
When Condition.columnCondition is a CompositeColumnValueCondition, it contains the following parameters. Add subconditions with addCondition(). You can add up to 32 subconditions.
|
Name |
Type |
Description |
|
type (required) |
LogicOperator |
The logical operator. Valid values:
|
|
conditions (required) |
List<ColumnCondition> |
The subconditions for the logical operation. Add each subcondition with |
Examples
Single column value condition
Use SingleColumnValueCondition to check a single attribute column value. The following example updates col2 for the row with primary key row1 only when col1 == "changed_val1".
PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"))
.build();
RowUpdateChange rowUpdateChange = new RowUpdateChange("condition_demo", primaryKey);
rowUpdateChange.put("col2", ColumnValue.fromString("new_val2"));
Condition condition = new Condition();
SingleColumnValueCondition singleCondition = new SingleColumnValueCondition(
"col1",
SingleColumnValueCondition.CompareOperator.EQUAL,
ColumnValue.fromString("changed_val1"));
condition.setColumnCondition(singleCondition);
rowUpdateChange.setCondition(condition);
client.updateRow(new UpdateRowRequest(rowUpdateChange));
Composite column value condition
Use CompositeColumnValueCondition to combine multiple conditions with logical operators. You can nest composite conditions inside one another. The following example builds the condition (col1 == "changed_val1" AND col2 == "new_val2") OR (col3 == "val3").
PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"))
.build();
RowUpdateChange rowUpdateChange = new RowUpdateChange("condition_demo", primaryKey);
rowUpdateChange.put("col1", ColumnValue.fromString("final_val1"));
// Sub-condition: col1 == "changed_val1" AND col2 == "new_val2"
CompositeColumnValueCondition andCondition = new CompositeColumnValueCondition(
CompositeColumnValueCondition.LogicOperator.AND);
andCondition.addCondition(new SingleColumnValueCondition(
"col1",
SingleColumnValueCondition.CompareOperator.EQUAL,
ColumnValue.fromString("changed_val1")));
andCondition.addCondition(new SingleColumnValueCondition(
"col2",
SingleColumnValueCondition.CompareOperator.EQUAL,
ColumnValue.fromString("new_val2")));
// Top-level OR: (col1 AND col2) OR (col3)
CompositeColumnValueCondition orCondition = new CompositeColumnValueCondition(
CompositeColumnValueCondition.LogicOperator.OR);
orCondition.addCondition(andCondition);
orCondition.addCondition(new SingleColumnValueCondition(
"col3",
SingleColumnValueCondition.CompareOperator.EQUAL,
ColumnValue.fromString("val3")));
Condition condition = new Condition();
condition.setColumnCondition(orCondition);
rowUpdateChange.setCondition(condition);
client.updateRow(new UpdateRowRequest(rowUpdateChange));
Prevent concurrent overwrites
Implement compare-and-swap with conditional update: first read the current value, then pass it as the update condition. The update succeeds only when the column still holds the value you read. If another process modifies the column between your read and write, the update fails. This prevents you from overwriting that process's write.
PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"))
.build();
// 1. Read the current value.
SingleRowQueryCriteria queryCriteria = new SingleRowQueryCriteria("condition_demo", primaryKey);
queryCriteria.setMaxVersions(1);
GetRowResponse getResponse = client.getRow(new GetRowRequest(queryCriteria));
String oldValue = getResponse.getRow().getLatestColumn("col1").getValue().asString();
// 2. Perform a conditional update based on the value just read (only update if col1 still equals oldValue).
RowUpdateChange rowUpdateChange = new RowUpdateChange("condition_demo", primaryKey);
rowUpdateChange.put("col1", ColumnValue.fromString("cas_updated"));
Condition condition = new Condition(RowExistenceExpectation.EXPECT_EXIST);
SingleColumnValueCondition casCondition = new SingleColumnValueCondition(
"col1",
SingleColumnValueCondition.CompareOperator.EQUAL,
ColumnValue.fromString(oldValue));
casCondition.setPassIfMissing(false);
casCondition.setLatestVersionsOnly(true);
condition.setColumnCondition(casCondition);
rowUpdateChange.setCondition(condition);
client.updateRow(new UpdateRowRequest(rowUpdateChange));