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