只有滿足條件時,才能對資料表中的資料進行更新;當不滿足條件時,更新失敗並給使用者報錯。

前提條件

  • 已初始化OTSClient。具體操作,請參見初始化
  • 已建立資料表並寫入資料。

使用方法

在通過PutRow、UpdateRow、DeleteRow或BatchWriteRow介面更新資料時,可以使用條件更新檢查行存在性條件和列條件,只有滿足條件時才能更新成功。

條件更新包括行存在性條件和列條件。

  • 行存在性條件:包括IGNORE、EXPECT_EXIST和EXPECT_NOT_EXIST,分別代表忽略、期望存在和期望不存在。

    對資料表變更操作時,系統會先檢查行存在性條件,如果不滿足行存在性條件,則更改失敗並給使用者報錯。

  • 列條件:包括SingleColumnValueCondition和CompositeColumnValueCondition,是基於某一列或者某些列的列值進行條件判斷。如果不滿足列條件,則更改失敗並給使用者報錯。
    • SingleColumnValueCondition支援一列和一個常量比較。不支援兩列或者兩個常量相比較。
    • CompositeColumnValueCondition的內節點為邏輯運算,子條件可以是SingleColumnValueCondition或CompositeColumnValueCondition。

條件更新可以實現樂觀鎖功能,即在更新某行時,先擷取某列的值,假設為列A,值為1,然後設定條件列A=1,更新行使列A=2。如果更新失敗,表示有其他用戶端已成功更新該行。

限制

條件更新的列條件支援關係運算(=、!=、>、>=、<、<=)和邏輯運算(NOT、AND、OR),最多支援10個條件的組合。

參數

參數 說明
RowExistenceExpectation 對資料表變更操作時,系統會先檢查行存在性條件,如果不滿足行存在性條件,則更改失敗並給使用者報錯。

行存在性條件包括IGNORE、EXPECT_EXIST和EXPECT_NOT_EXIST。

  • IGNORE:表示忽略,不做任何存在性檢查。
  • EXPECT_EXIST:表示期望存在,如果該行存在,則滿足條件;如果該行不存在,則不滿足條件。
  • EXPECT_NOT_EXIST:期望行不存在,如果該行不存在,則滿足條件;如果該行存在,則不滿足條件。
ColumnName 列的名稱。
ColumnValue 列的對比值。
CompareOperator 對列值進行比較的關係運算子。關於類型的更多資訊,請參見ComparatorType

關係運算子包括EQUAL(=)、NOT_EQUAL(!=)、GREATER_THAN(>)、GREATER_EQUAL(>=)、LESS_THAN(<)和LESS_EQUAL(<=)。

LogicOperator 對多個條件進行組合的邏輯運算子。關於類型的更多資訊,請參見LogicalOperator

邏輯運算子包括NOT、AND和OR。

邏輯運算子不同可以添加的子條件個數不同。
  • 當邏輯運算子為NOT時,只能添加一個子條件。
  • 當邏輯運算子為AND或OR時,必須至少添加兩個子條件。
PassIfMissing 當列在某行中不存在時,條件檢查是否通過。類型為bool值,預設值為true,表示如果列在某行中不存在時,則條件檢查通過,該行滿足更新條件。

當設定PassIfMissing為false時,如果列在某行中不存在時,則條件檢查不通過,該行不滿足更新條件。

LatestVersionsOnly 當列存在多個版本的資料時,是否只使用最新版本的值做比較。類型為bool值,預設值為true,表示如果列存在多個版本的資料時,則只使用該列最新版本的值進行比較。

當設定LatestVersionsOnly為false時,如果列存在多個版本的資料時,則會使用該列的所有版本的值進行比較,此時只要有一個版本的值滿足條件,就條件檢查通過,該行滿足更新條件。

樣本

使用列判斷條件和樂觀鎖的範例程式碼如下:

  • 構造SingleColumnValueCondition。
     //設定條件為Col0==0。
     SingleColumnValueCondition singleColumnValueCondition = new SingleColumnValueCondition("Col0",
             SingleColumnValueCondition.CompareOperator.EQUAL, ColumnValue.fromLong(0));
     //如果不存在Col0列,條件檢查不通過。
     singleColumnValueCondition.setPassIfMissing(false);
     //只判斷最新版本。
     singleColumnValueCondition.setLatestVersionsOnly(true);
                        
  • 構造CompositeColumnValueCondition。
     //composite1的條件為(Col0 == 0) AND (Col1 > 100)。
     CompositeColumnValueCondition composite1 = new CompositeColumnValueCondition(CompositeColumnValueCondition.LogicOperator.AND);
     SingleColumnValueCondition single1 = new SingleColumnValueCondition("Col0",
             SingleColumnValueCondition.CompareOperator.EQUAL, ColumnValue.fromLong(0));
     SingleColumnValueCondition single2 = new SingleColumnValueCondition("Col1",
             SingleColumnValueCondition.CompareOperator.GREATER_THAN, ColumnValue.fromLong(100));
     composite1.addCondition(single1);
     composite1.addCondition(single2);
    
     //composite2的條件為( (Col0 == 0) AND (Col1 > 100) ) OR (Col2 <= 10)。
     CompositeColumnValueCondition composite2 = new CompositeColumnValueCondition(CompositeColumnValueCondition.LogicOperator.OR);
     SingleColumnValueCondition single3 = new SingleColumnValueCondition("Col2",
             SingleColumnValueCondition.CompareOperator.LESS_EQUAL, ColumnValue.fromLong(10));
     composite2.addCondition(composite1);
     composite2.addCondition(single3);     
                        
  • 通過Condition實現樂觀鎖機制,遞增一列。
     private static void updateRowWithCondition(SyncClient client, String pkValue) {
         //構造主鍵。
         PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
         primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(pkValue));
         PrimaryKey primaryKey = primaryKeyBuilder.build();
    
         //讀取一行資料。
         SingleRowQueryCriteria criteria = new SingleRowQueryCriteria(TABLE_NAME, primaryKey);
         criteria.setMaxVersions(1);
         GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
         Row row = getRowResponse.getRow();
         long col0Value = row.getLatestColumn("Col0").getValue().asLong();
    
         //條件更新Col0列,使列值加1。
         RowUpdateChange rowUpdateChange = new RowUpdateChange(TABLE_NAME, primaryKey);
         Condition condition = new Condition(RowExistenceExpectation.EXPECT_EXIST);
         ColumnCondition columnCondition = new SingleColumnValueCondition("Col0", SingleColumnValueCondition.CompareOperator.EQUAL, ColumnValue.fromLong(col0Value));
         condition.setColumnCondition(columnCondition);
         rowUpdateChange.setCondition(condition);
         rowUpdateChange.put(new Column("Col0", ColumnValue.fromLong(col0Value + 1)));
    
         try {
             client.updateRow(new UpdateRowRequest(rowUpdateChange));
         } catch (TableStoreException ex) {
             System.out.println(ex.toString());
         }
     }