全部產品
Search
文件中心

Tablestore:條件更新

更新時間:Jun 26, 2026

Java SDK 在寫入或刪除行時附加判斷條件,目標行滿足條件才執行操作,否則返回錯誤。可用於實現樂觀鎖、避免覆蓋未讀資料等情境。

前提條件

安裝 Tablestore Java SDK並初始化用戶端。

功能說明

public class Condition {
    private RowExistenceExpectation rowExistenceExpectation;
    private ColumnCondition columnCondition;
}

Condition 包含行存在性條件rowExistenceExpectation)和列值判斷條件columnCondition)兩部分,兩者可獨立使用或組合使用。通過 RowPutChange / RowUpdateChange / RowDeleteChangesetCondition 方法附加到寫操作。條件不滿足時服務端返回錯誤,行資料不被修改。

以下樣本對資料表 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

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

  • IGNORE(預設):不做行存在性判斷。

  • EXPECT_EXIST:資料表中存在目標行資料時滿足條件,否則不滿足。

  • EXPECT_NOT_EXIST:資料表中不存在目標行資料時滿足條件,否則不滿足。

columnCondition(可選)

ColumnCondition

列值判斷條件,子類包括 SingleColumnValueCondition(單列值判斷)和 CompositeColumnValueCondition(組合判斷)。

SingleColumnValueCondition

public class SingleColumnValueCondition extends ColumnCondition

呼叫簽章:new SingleColumnValueCondition(columnName, operator, columnValue)

名稱

類型

說明

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 時,任意版本符合條件即視為滿足。

CompositeColumnValueCondition

public class CompositeColumnValueCondition extends ColumnCondition

呼叫簽章:new CompositeColumnValueCondition(logicOperator),再通過 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));

樂觀鎖 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));