条件更新

更新时间:
复制 MD 格式

Java SDK 在写入、更新或删除行时设置判断条件,仅在目标行满足条件时执行操作。

前提条件

安装 Tablestore Java SDK并初始化客户端。

功能说明

Condition 包含行存在性条件rowExistenceExpectation)和列值判断条件columnCondition),两者可独立设置或组合使用。通过 RowPutChangeRowUpdateChangeRowDeleteChangesetCondition 方法设置条件;这些行变更对象也可加入 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 包含以下参数。行存在性条件和列值条件可独立设置或组合使用;当 rowExistenceExpectationIGNORE 且未设置 columnCondition 时,不执行条件判断。

名称

类型

说明

rowExistenceExpectation(可选)

RowExistenceExpectation

行存在性条件,取值包括:

  • IGNORE(默认):不做行存在性判断。

  • EXPECT_EXIST:数据表中存在目标行数据时满足条件,否则不满足。

  • EXPECT_NOT_EXIST:数据表中不存在目标行数据时满足条件,否则不满足。

columnCondition(可选)

ColumnCondition

列值判断条件,子类包括 SingleColumnValueCondition(单列值判断)和 CompositeColumnValueCondition(组合判断)。

单列值判断

Condition.columnCondition 使用 SingleColumnValueCondition 时,包含以下参数。

名称

类型

说明

columnName(必选)

String

判断的属性列名称。

operator(必选)

CompareOperator

关系运算符,取值包括:

  • EQUAL(等于)

  • NOT_EQUAL(不等于)

  • GREATER_THAN(大于)

  • GREATER_EQUAL(大于等于)

  • LESS_THAN(小于)

  • LESS_EQUAL(小于等于)

columnValue(必选)

ColumnValue

判断的值。

passIfMissing(可选)

boolean

行数据不包含目标属性列时是否视为满足条件。默认 true(视为满足)。

设置为 false 时,行不包含目标列即视为不满足。

latestVersionsOnly(可选)

boolean

是否只判断最新的数据版本。默认 true(只判断最新版本)。

设置为 false 时,任意版本符合条件即视为满足。

组合条件

Condition.columnCondition 使用 CompositeColumnValueCondition 时,包含以下参数。通过 addCondition() 添加子条件,最多支持 32 个条件

名称

类型

说明

type(必选)

LogicOperator

逻辑运算符,取值包括:

  • AND(与),至少添加两个子条件。

  • OR(或),至少添加两个子条件。

  • NOT(非),只能添加一个子条件。

conditions(必选)

List<ColumnCondition>

参与逻辑运算的子条件列表,通过 addCondition() 添加。子条件可以是 SingleColumnValueConditionCompositeColumnValueCondition(支持嵌套)。

场景示例

单列值条件

通过 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));