Introduction to Tablestore - UpdateRow interface details

Keywords: Java SDK network github

The introduction manual series of table store mainly introduces various functional interfaces and applicable scenarios of table store to help customers understand and use table store. This paper introduces the UpdateRow interface of table store, including its parameters, function examples, usage scenarios, etc.

Interface Overview

The UpdateRow interface is one of the basic read-write interfaces provided by the table store. It is used to update a row. If the specified row does not exist, UpdateRow can also be used to add a row. The update here includes adding, modifying, or deleting a column. If you use the multi version function, you can also add, modify, or delete the version specified in a column. In addition, you can specify conditions in the interface parameters, which are updated only when the conditions are met. The following details the parameters and functions of the interface.

Interface parameter description

API definition and parameter description

First, the API definition of the UpdateRow interface:

message UpdateRowRequest {
    required string table_name = 1;
    required bytes row_change = 2;
    required Condition condition = 3;
    optional ReturnContent return_content = 4; 
}

message UpdateRowResponse {
    required ConsumedCapacity consumed = 1;
    optional bytes row = 2;
}

For the specific parameters in the API definition, see the API document on the official website: https://help.aliyun.com/document_detail/27307.html

SDK interface and parameter description

In the project code, the table storage Tablestore is read and written through the SDKs of various languages published by the table storage Tablestore. The SDKs encapsulate the API and automatically process the request encoding and response parsing internally. Therefore, for users of table storage, they only need to be familiar with the SDK interface.

Take the Java SDK as an example to introduce the UpdateRow interface and parameters in the SDK.

Interface definition

Syncclient:

    /**
     * Update a row of data in the table.
     * <p>If the row to be updated does not exist, a new row of data is written. </p>
     * <p>Update operations can include writing a new property column or deleting one or more versions of a property column. </p>
     *
     * @param updateRowRequest Parameters required to perform the UpdateRow operation.
     * @return TableStore Results returned by the service
     * @throws TableStoreException    TableStore Exception returned by service
     * @throws ClientException The return result of the request is invalid or a network exception was encountered
     */
    public UpdateRowResponse updateRow(UpdateRowRequest updateRowRequest)
            throws TableStoreException, ClientException;

Asynchronous client:

    /**
     * Update a row of data in the table.
     * <p>If the row to be updated does not exist, a new row of data is written. </p>
     * <p>Update operations can include writing a new property column or deleting one or more versions of a property column. </p>
     *
     * @param updateRowRequest Parameters required to perform the UpdateRow operation.
     * @param callback The callback function invoked after the request is completed can be null, which means that no callback function is required.
     * @return Get the Future of the result
     * @throws TableStoreException TableStore Exception returned by service
     * @throws ClientException The return result of the request is invalid or a network exception was encountered
     */
    public Future<UpdateRowResponse> updateRow(
            UpdateRowRequest updateRowRequest, TableStoreCallback<UpdateRowRequest, UpdateRowResponse> callback);

Specific parameter description:

Variable type Explain Remarks
UpdateRowRequest The request type of the UpdateRow interface. See the following instructions for details.
UpdateRowResponse The result of the UpdateRow interface is shown in the following instructions.
TableStoreCallback callback Asynchronous callback function for UpdateRow interface. Only for asynchronous interfaces.
Future The UpdateRow interface of the asynchronous interface returns results. Only for asynchronous interfaces.
After the asynchronous interface is called, it does not wait for the end of the request, and immediately returns to future. The actual interface response results can be obtained through future.get().

Updaterowlequest parameter description

Specific parameter description:

Variable type Explain Remarks
Txnrequest (base class) Abstract class, which contains the TransactionId member variable. The request type that inherits this class can be used in local transactions. For the use of TransactionId, please refer to the document of local transaction.
UpdateRowRequest The request type of the UpdateRow interface, which contains a member variable: RowUpdateChange.
Inherited from TxnRequest, indicating that the request can be used in a local transaction.
RowUpdateChange Specific request parameters of this update.

RowUpdateChange parameter description

Specific parameter description:

Variable type Class description Member variable or interface Explain
Rowchange (base class) The base class of RowUpdateChange provides common parameters such as setting table name, primary key, update condition and return type. tableName Specifies the name of the table to be operated on by this update.
primaryKey Specifies the primary key of the row for this secondary update.
condition Specify the conditions for this update operation, optional.
returnType Enumeration type, RT_NONE by default, means that the content of the row is not returned. In addition, there are two values:
(1)RT_PK: returns the primary key, which is suitable for scenarios using the auto increment column function of the primary key, and is used to return the auto increment primary key value generated by the system.
(2) RT > after > Modify: returns the data of the modified column, which is applicable to the scenario where the atom addition function is used. It is used to return the value of a column after the atom addition. You need to set returnColumnNames.
returnColumnNames When the returnType is RT > after > Modify, specify the column name of the modified column to be returned (applicable to the scene of atomic addition).
RowUpdateChange The specific request parameters of UpdateRow are inherited from the RowChange class. put(String columnName, ColumnValue value) Add or modify the value of a column.
(a new version number will be generated for this column in the system. In single version mode, you do not need to care about this version number.)
put(String columnName, ColumnValue value, long version) Add or modify a version of a column.
(applicable to multi version mode, manually specifying version number to write)
put(Column column) The function is the same as the put interface above, except that the parameters are encapsulated with Column type.
put(List column) The function is the same as the put interface above, except that the parameters are multiple columns.
deleteColumns(String columnName) Delete a column. In multi version mode, all versions of the column will be deleted.
deleteColumn(String columnName, long version) Deleting the specified version of a column is applicable to deleting a specific version in multi version mode.
increment(Column column) Add an atom to a column, only for integer types.
Condition Conditions of this update. You can specify row existence conditions and column conditions, such as "the value of a column is greater than 5". rowExistenceExpectation Row existence condition, enumeration type, with the following three values:
(1) IGNORE: do not judge the existence of rows. IGNORE is the default.
(2) EXPECT_EXIST: the row is expected to exist. If it does not exist, the request will report an error.
(3) Expect not exist: the row is not expected to exist. If it exists, the request will report an error.
Be careful:
In general, if there is no special requirement for setting conditions, use IGNORE (keep the default and do not set), and the write performance is better.
columnCondition Column condition: you can set single column value condition or composite column value condition. For details, see the document of condition update.

UpdateRowResponse parameter description

Specific parameter description:

Variable type Member variable or interface Explain
Response (base class) requestId The requestId returned by the request server is used for problem investigation. It is recommended to print it to the business log in case of error.
traceId traceId generated by the SDK is used for problem investigation. It is recommended to print it to the business log when there is an error.
UpdateRowResponse consumedCapacity The read-write CU consumed in this request is used for billing.
row By default, it is null. Only when the returnType in the request is set to return pK (RT ﹣ PK) or the modified value of a column (RT ﹣ after ﹣ modify), the corresponding content is returned.

Functional example

All sample code can be viewed in the tablestore examples project.

Github address: https://github.com/aliyun/tablestore-examples/tree/master/basic/Java/DataManage/src/main/java/com/aliyun/tablestore/basic/dataManage

Basic update operation

The most common scenario of the UpdateRow interface is to write some columns to a row or delete some columns. Generally, there are many single version tables used in business. At this time, the concept of multiple versions on columns can be ignored, and each column has only one value to understand. At this time, UpdateRow is used to add, modify or delete some columns.

New: if the written attribute column does not exist before, it will be added after UpdateRow is executed.
Modify: if the written property column already has a value, the value of the column will be modified after UpdateRow is executed.
Delete: UpdateRow can be used to delete some columns. If the column does not exist before, it has no effect and no error will be reported.

Sample code

The following code performs an UpdateRow operation to add two columns to a row and delete one column.

    public void updateRowNormally() {
        PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
                .addPrimaryKeyColumn(PK1, PrimaryKeyValue.fromLong(1L))
                .addPrimaryKeyColumn(PK2, PrimaryKeyValue.fromString("string"))
                .build();
        /**
         * Construct RowUpdateChange, set the table name and primary key
         */
        RowUpdateChange rowChange = new RowUpdateChange(TABLE_NAME, primaryKey);

        /**
         * Write two columns
         */
        rowChange.put("col_str", ColumnValue.fromString("value1"));
        rowChange.put("col_long", ColumnValue.fromLong(1));

        /**
         * Delete a column
         */
        rowChange.deleteColumns("col_to_delete");

        /**
         * Construct updaterowlequest
         */
        UpdateRowRequest updateRowRequest = new UpdateRowRequest(rowChange);

        /**
         * Call the updateRow interface. If the previous line does not exist, the system will add it.
         */
        UpdateRowResponse updateRowResponse = syncClient.updateRow(updateRowRequest);

        /**
         * Print requestID
         */
        System.out.printf("UpdateRowSuccess, request id: %s\n", updateRowResponse.getRequestId());
    }

Using UpdateRow to add, modify, or delete some columns is the most basic single row data update operation and also a very common scenario.

However, in some scenarios, if you use the multi version function of table storage, you may need to add or modify a specific version of a column, or delete a version of a column. In this case, you need to specify a timestamp to update or delete. See the following example.

Specify version action

For tables with multiple versions set, the latest N versions will be kept on each column. UpdateRow can update or delete a specific version.

Sample code

The following code performs an UpdateRow operation, writes two columns to a row, specifies the version number, and deletes a version of a column, as well as the version number to be deleted.

Note: when specifying the version number, it is necessary to ensure that the version number is within the maximum version deviation set on the table. If it exceeds the deviation range, you can adjust the maximum version deviation setting on the table (see the document: https://help.aliyun.com/document_detail/89939.html).

    public void updateRowMultiVersion() {
        PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
                .addPrimaryKeyColumn(PK1, PrimaryKeyValue.fromLong(1L))
                .addPrimaryKeyColumn(PK2, PrimaryKeyValue.fromString("string"))
                .build();
        /**
         * Construct RowUpdateChange, set the table name and primary key
         */
        RowUpdateChange rowChange = new RowUpdateChange(TABLE_NAME, primaryKey);

        long version = System.currentTimeMillis();

        /**
         * Write two columns and specify the version number.
         * If the specified version does not exist before, a new version will be added; if the version already exists, the value of the version will be modified.
         */
        rowChange.put("col_str", ColumnValue.fromString("value1"), version);
        rowChange.put("col_long", ColumnValue.fromLong(1), version);

        /**
         * Delete a version of a column and specify the version number.
         */
        rowChange.deleteColumn("col_to_delete", version);

        /**
         * Construct updaterowlequest
         */
        UpdateRowRequest updateRowRequest = new UpdateRowRequest(rowChange);

        /**
         * Call the updateRow interface. If the previous line does not exist, the system will add it.
         */
        UpdateRowResponse updateRowResponse = syncClient.updateRow(updateRowRequest);

        /**
         * Print requestID
         */
        System.out.printf("UpdateRowSuccess, request id: %s\n", updateRowResponse.getRequestId());
    }

Condition updating

The UpdateRow interface can set update conditions, which can only be updated when the conditions are met, including row existence conditions and column conditions.

Row existence condition: check whether the row exists or does not exist before updating, and update only when it meets the expectation, otherwise it will be thrown in error.

Column condition: at present, SingleColumnValueCondition and CompositeColumnValueCondition are supported. They are based on the column values of a column or some columns, such as "the value of column" should be greater than 5 ". Based on column conditions, table store can be used to implement distributed optimistic locking mechanism.

Function document of condition update: https://help.aliyun.com/document_detail/35194.html

Sample code

Set the row existence condition and column condition:

    public void updateRowWithCondition() {
        PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
                .addPrimaryKeyColumn(PK1, PrimaryKeyValue.fromLong(1L))
                .addPrimaryKeyColumn(PK2, PrimaryKeyValue.fromString("string"))
                .build();
        /**
         * Construct RowUpdateChange, set the table name and primary key
         */
        RowUpdateChange rowChange = new RowUpdateChange(TABLE_NAME, primaryKey);

        /**
         * Set the line existence condition for the expected line existence
         */
        Condition condition = new Condition(RowExistenceExpectation.EXPECT_EXIST);

        /**
         * Set the column condition. If you only need to check the row existence, you can not set the column condition.
         *
         * Here, set the column condition to the combination condition of two columns: "Col. & Boolean = = true & (Col. & long > 0)"
         */
        CompositeColumnValueCondition colCondition = new CompositeColumnValueCondition(CompositeColumnValueCondition.LogicOperator.AND);
        SingleColumnValueCondition subColCondition1 = new SingleColumnValueCondition(
                "col_boolean",
                SingleColumnValueCondition.CompareOperator.EQUAL,
                ColumnValue.fromBoolean(true));
        subColCondition1.setPassIfMissing(true); // setPassIfMissing(true), indicating that if the column does not exist, it is also considered to meet the condition.
        SingleColumnValueCondition subColCondition2 = new SingleColumnValueCondition(
                "col_long",
                SingleColumnValueCondition.CompareOperator.GREATER_THAN,
                ColumnValue.fromLong(0L));
        colCondition.addCondition(subColCondition1).addCondition(subColCondition2);
        subColCondition2.setPassIfMissing(false); // setPassIfMissing(false), which means that if the column does not exist, it is regarded as not satisfying the condition.

        condition.setColumnCondition(colCondition);
        rowChange.setCondition(condition);

        /**
         * Write two columns when conditions are met
         */
        rowChange.put("col_str", ColumnValue.fromString("value1"));
        rowChange.put("col_long", ColumnValue.fromLong(1));

        /**
         * Construct updaterowlequest
         */
        UpdateRowRequest updateRowRequest = new UpdateRowRequest(rowChange);

        /**
         * Call the updateRow interface.
         * If the set conditions are not met, such as the row does not exist or the column conditions are not met, the OTSException will be thrown, and the ErrorCode will be "OTSConditionCheckFail"
         */
        UpdateRowResponse updateRowResponse = syncClient.updateRow(updateRowRequest);

        /**
         * Print requestID
         */
        System.out.printf("UpdateRowSuccess, request id: %s\n", updateRowResponse.getRequestId());
    }

Atomic counter

UpdateRow supports atomic addition to an integer column. Atomic addition can be used to incrementally change the data of an integer column, such as adding 10, or subtracting 5, etc. on the original basis. The atom plus operation can be used to construct an atom counter.

Function document of atomic counter: https://help.aliyun.com/document_detail/90949.html

Sample code

    public void updateRowIncrement() {
        PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
                .addPrimaryKeyColumn(PK1, PrimaryKeyValue.fromLong(1L))
                .addPrimaryKeyColumn(PK2, PrimaryKeyValue.fromString("string"))
                .build();
        /**
         * Construct RowUpdateChange, set the table name and primary key
         */
        RowUpdateChange rowChange = new RowUpdateChange(TABLE_NAME, primaryKey);

        String columnName = "col_long";
        /**
         * Add 100 atoms to col long column.
         * If the column does not exist before, it will be accumulated from 0.
         */
        rowChange.increment(new Column(columnName, ColumnValue.fromLong(100)));

        /**
         * Set to return the modified column value.
         */
        rowChange.setReturnType(ReturnType.RT_AFTER_MODIFY);
        rowChange.addReturnColumn(columnName);

        /**
         * Construct updaterowlequest
         */
        UpdateRowRequest updateRowRequest = new UpdateRowRequest(rowChange);

        /**
         * Call the updateRow interface. If the previous row does not exist, the system will add it.
         */
        UpdateRowResponse updateRowResponse = syncClient.updateRow(updateRowRequest);

        /**
         * Print the modified value and RequestId of the column
         */
        System.out.printf("UpdateRowSuccess, column [%s] was updated to %d, request id: %s\n",
                columnName,
                updateRowResponse.getRow().getLatestColumn(columnName).getValue().asLong(),
                updateRowResponse.getRequestId());
    }

Expert services

If you have any questions or need better online support, welcome to join pin group: "open communication group of form storage". Free online expert service is provided in the group, welcome to scan code to join, group number: 23307953

Posted by crwtrue on Sun, 12 Jan 2020 22:41:59 -0800