Java SDK 在写入或删除行时附加判断条件,目标行满足条件才执行操作,否则返回错误。可用于实现乐观锁、避免覆盖未读数据等场景。
前提条件
安装 Tablestore Java SDK并初始化客户端。
功能说明
public class Condition {
private RowExistenceExpectation rowExistenceExpectation;
private ColumnCondition columnCondition;
}Condition 包含行存在性条件(rowExistenceExpectation)和列值判断条件(columnCondition)两部分,两者可独立使用或组合使用。通过 RowPutChange / RowUpdateChange / RowDeleteChange 的 setCondition 方法附加到写操作。条件不满足时服务端返回错误,行数据不被修改。
以下示例对数据表 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);
UpdateRowResponse response = client.updateRow(new UpdateRowRequest(rowUpdateChange));
System.out.println("RequestId: " + response.getRequestId());
System.out.println("Write CU: " + response.getConsumedCapacity().getCapacityUnit().getWriteCapacityUnit());参数说明
Condition
Condition 是条件容器,包含行存在性条件和列值条件两类字段。两类可独立设置或组合使用,但至少需要设置其中一项才有实际筛选效果。
名称 | 类型 | 说明 |
rowExistenceExpectation(可选) | RowExistenceExpectation | 行存在性条件,取值包括:
|
columnCondition(可选) | ColumnCondition | 列值判断条件,子类包括 |
SingleColumnValueCondition
public class SingleColumnValueCondition extends ColumnCondition调用签名:new SingleColumnValueCondition(columnName, operator, columnValue)。
名称 | 类型 | 说明 |
columnName(必选) | String | 判断的属性列名称。 |
operator(必选) | CompareOperator | 关系运算符,取值包括:
|
columnValue(必选) | ColumnValue | 判断的值。 |
passIfMissing(可选) | boolean | 行数据不包含目标属性列时是否视为满足条件。默认 设置为 |
latestVersionsOnly(可选) | boolean | 是否只判断最新的数据版本。默认 设置为 |
CompositeColumnValueCondition
public class CompositeColumnValueCondition extends ColumnCondition调用签名:new CompositeColumnValueCondition(logicOperator),再通过 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));乐观锁 CAS
利用条件更新实现 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));