Java SDK 在写入、更新或删除行时设置判断条件,仅在目标行满足条件时执行操作。
前提条件
安装 Tablestore Java SDK并初始化客户端。
功能说明
Condition 包含行存在性条件(rowExistenceExpectation)和列值判断条件(columnCondition),两者可独立设置或组合使用。通过 RowPutChange、RowUpdateChange 或 RowDeleteChange 的 setCondition 方法设置条件;这些行变更对象也可加入 BatchWriteRow 请求。条件不满足时,服务端返回错误且不修改行数据。
rowChange.setCondition(condition)
new SingleColumnValueCondition(columnName, operator, columnValue)
new CompositeColumnValueCondition(logicOperator)
以下示例对数据表 condition_demo 中主键 row1 的行执行更新,仅当该行存在时才更新(行不存在则返回错误)。
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));
参数说明
更新条件
Condition 包含以下参数。行存在性条件和列值条件可独立设置或组合使用;当 rowExistenceExpectation 为 IGNORE 且未设置 columnCondition 时,不执行条件判断。
|
名称 |
类型 |
说明 |
|
rowExistenceExpectation(可选) |
RowExistenceExpectation |
行存在性条件,取值包括:
|
|
columnCondition(可选) |
ColumnCondition |
列值判断条件,子类包括 |
单列值判断
Condition.columnCondition 使用 SingleColumnValueCondition 时,包含以下参数。
|
名称 |
类型 |
说明 |
|
columnName(必选) |
String |
判断的属性列名称。 |
|
operator(必选) |
CompareOperator |
关系运算符,取值包括:
|
|
columnValue(必选) |
ColumnValue |
判断的值。 |
|
passIfMissing(可选) |
boolean |
行数据不包含目标属性列时是否视为满足条件。默认 设置为 |
|
latestVersionsOnly(可选) |
boolean |
是否只判断最新的数据版本。默认 设置为 |
组合条件
Condition.columnCondition 使用 CompositeColumnValueCondition 时,包含以下参数。通过 addCondition() 添加子条件,最多支持 32 个条件。
|
名称 |
类型 |
说明 |
|
type(必选) |
LogicOperator |
逻辑运算符,取值包括:
|
|
conditions(必选) |
List<ColumnCondition> |
参与逻辑运算的子条件列表,通过 |
场景示例
单列值条件
通过 SingleColumnValueCondition 判断单个属性列值。以下示例对主键 row1 的行更新 col2,仅当 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));
组合列值条件
通过 CompositeColumnValueCondition 用逻辑运算符组合多个条件,支持嵌套。以下示例构造条件 (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"));
// 子条件: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")));
// 顶层 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));
防止并发覆盖
利用条件更新实现 Compare-and-Swap:先读取原值,再用读到的值作为更新条件。仅当列值仍等于读到的值时才执行更新;若期间有其他进程修改了该列,本次更新失败,确保不覆盖未读到的并发修改。
PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"))
.build();
// 1. 读取原值
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. 基于读到的旧值做条件更新(只有 col1 仍等于 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));