すべてのプロダクト
Search
ドキュメントセンター

Tablestore:条件付き更新の実行

最終更新日:Dec 28, 2024

指定された条件が満たされた場合にのみ、データテーブルのデータを更新するために条件付き更新機能を使用できます。条件が満たされない場合、更新は失敗します。

前提条件

  • OTSClient インスタンスが初期化されていること。詳細については、クライアントの初期化を参照してください。

  • データテーブルが作成され、データがデータテーブルに書き込まれていること。

使用上の注意

PutRowUpdateRowDeleteRow、または BatchWriteRow 操作を呼び出してデータテーブルのデータを更新する場合、行存在条件と列ベースの条件を指定して条件付き更新を実行できます。データテーブルのデータは、条件が満たされた場合にのみ更新されます。

条件付き更新に行存在条件と列ベースの条件を指定できます。

  • 列ベースの条件

    列ベースの条件には、SingleColumnValueConditions と CompositeColumnValueConditions が含まれ、1 つ以上の列の値に基づいて条件ベースの判断を実行するために使用されます。列ベースの条件は、Tablestore フィルターで使用される条件に似ています。

    列ベースの条件は、=, !=, >, >=, <, <= NOT, AND, OR などの関係演算子と論理演算子をサポートしています。条件付き更新には最大 10 個の列ベースの条件を指定できます。

    • SingleColumnValueCondition を使用すると、列を定数と比較できます。SingleColumnValueCondition は、2 つの列または 2 つの定数の比較をサポートしていません。

    • CompositeColumnValueCondition は、複数の SingleColumnValueConditions または CompositeColumnValueConditions で構成されます。サブ条件間の論理関係を指定する必要があります。

  • 行存在条件

    データテーブルを更新すると、Tablestore は最初に、行存在条件が満たされているかどうかを確認します。行存在条件が満たされていない場合、更新は失敗し、エラーが報告されます。

    IGNORE、EXPECT_EXIST、EXPECT_NOT_EXIST などの行存在条件がサポートされています。

パラメーター

パラメーター

説明

RowExistenceExpectation

データテーブルを更新すると、Tablestore は最初に、行存在条件が満たされているかどうかを確認します。行存在条件が満たされていない場合、更新は失敗し、エラーが報告されます。

以下の行存在条件がサポートされています:IGNORE、EXPECT_EXIST、EXPECT_NOT_EXIST。

  • IGNORE:行の有無は無視されます。行存在チェックは実行されません。

  • EXPECT_EXIST:行が存在することが想定されます。行が存在する場合、条件は満たされます。

  • EXPECT_NOT_EXIST:行が存在しないことが想定されます。行が存在しない場合、条件は満たされます。

ColumnName

列の名前。

ColumnValue

列と比較する値。

CompareOperator

値の比較に使用する関係演算子。詳細については、ComparatorType を参照してください。

=, !=, >, >=, <, <= などの関係演算子がサポートされています。

LogicOperator

複数の条件を組み合わせるために使用する論理演算子。詳細については、LogicalOperator を参照してください。

NOT、AND、OR などの関係演算子がサポートされています。必要なサブ条件の数は、論理演算子によって異なります。

  • 論理演算子が NOT の場合、追加できるサブ条件は 1 つだけです。

  • 論理演算子が AND または OR の場合、少なくとも 2 つのサブ条件を追加する必要があります。

PassIfMissing

行に列が存在しない場合に条件チェックに合格するかどうかを指定します。このパラメーターの値はブール型です。デフォルト値は true です。これは、行に列が存在しない場合、条件チェックに合格し、行が更新条件を満たすことを示します。

PassIfMissing パラメーターを false に設定すると、行に列が存在しない場合、条件チェックは失敗します。

LatestVersionsOnly

列に複数のバージョンの値がある場合に最新バージョンの値のみを使用するかどうかを指定します。このパラメーターの値はブール型です。デフォルト値は true です。これは、列に複数のバージョンのデータがある場合、最新バージョンの値のみが比較に使用されることを示します。

LatestVersionsOnly パラメーターを false に設定すると、列に複数のバージョンのデータがある場合、すべてのバージョンの列値が比較に使用されます。この場合、いずれかのバージョンの値が条件を満たすと、条件チェックに合格します。

次の例は、列ベースの条件と楽観的ロックに基づいてデータを更新する方法を示しています。

列ベースの条件に基づいてデータを更新する

  • SinglleColumnValueCondition を構築する

    次の例では、Col0 列の値が Col0==0 の条件を満たす場合、値が更新されます。

    private static void updateRowWithSingleColumnValueCondition(SyncClient client, String pkValue){
        // プライマリキーを構築します。
        PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn("pk", 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();
    
        // データテーブルの名前を指定します。
        RowUpdateChange rowUpdateChange = new RowUpdateChange("<TABLE_NAME>", primaryKey);
    
        // 条件を設定します:Col0==0。
        SingleColumnValueCondition singleColumnValueCondition = new SingleColumnValueCondition("Col0",
                SingleColumnValueCondition.CompareOperator.EQUAL, ColumnValue.fromLong(0));
        // Col0 列が存在しない場合、条件チェックは失敗します。
        singleColumnValueCondition.setPassIfMissing(false);
        // 最新バージョンのみが比較に使用されるように指定します。
        singleColumnValueCondition.setLatestVersionsOnly(true);
        Condition condition = new Condition();
        condition.setColumnCondition(singleColumnValueCondition);
        rowUpdateChange.setCondition(condition);
        // Col0 列の値が列ベースの条件を満たす場合、Col0 列の値は 1 ずつ増加します。
        rowUpdateChange.put(new Column("Col0", ColumnValue.fromLong(col0Value+1)));
        try {
            client.updateRow(new UpdateRowRequest(rowUpdateChange));
            System.out.println("データが更新されました。");
        } catch (TableStoreException ex) {
            System.out.println("データの更新に失敗しました。" + ex.toString());
        }
    }                 
  • CompositeColumnValueCondition を構築する

    次の例では、Col0 列の値が次のいずれかの条件を満たす場合、値が更新されます:Col0==0 AND Col1>100 および Col2<=10

    private static void updateRowWithCompositeColumnValueCondition(SyncClient client, String pkValue){
        // プライマリキーを構築します。
        PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn("pk", 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();
    
        // データテーブルの名前を指定します。
        RowUpdateChange rowUpdateChange = new RowUpdateChange("<TABLE_NAME>", primaryKey);
    
        // 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 condition = new Condition();
        condition.setColumnCondition(composite2);
        rowUpdateChange.setCondition(condition);
    		// Col0 列の値が列ベースの条件のいずれかを満たす場合、Col0 列の値は 1 ずつ増加します。
        rowUpdateChange.put(new Column("Col0", ColumnValue.fromLong(col0Value+1)));
        try {
            client.updateRow(new UpdateRowRequest(rowUpdateChange));
            System.out.println("データが更新されました。");
        } catch (TableStoreException ex) {
            System.out.println("データの更新に失敗しました。" + ex.toString());
        }
    }

楽観的ロックに基づいてデータを更新する

次のサンプルコードは、楽観的ロックに基づいて列の値を増やす方法の例を示しています。

次の例では、データテーブルから読み取られた値が Col0 列の現在の値と同じである場合、Col0 列の値が更新されます。

 private static void updateRowWithCondition(SyncClient client, String pkValue) {
     // プライマリキーを構築します。
     PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
     primaryKeyBuilder.addPrimaryKeyColumn("pk", 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());
     }
 }