全部產品
Search
文件中心

Tablestore:局部事務

更新時間:Jun 30, 2024

為資料表開啟局部事務後,使用局部事務功能,您可以建立資料範圍在一個分區索引值內的局部事務並對局部事務中的資料進行讀寫操作。通過使用局部事務您可以實現單行或多行讀寫的原子操作。

重要

使用Java SDK 5.11.0及以上版本時,您可以在建立資料表時開啟局部事務。更多資訊,請參見建立資料表

使用局部事務可以指定某個分區索引值內的操作是原子的,對分區索引值內的資料進行的操作要麼全部成功要麼全部失敗,並且所提供的隔離等級為讀已提交。

前提條件

  • 已初始化OTSClient。具體操作,請參見初始化OTSClient

  • 已建立資料表並寫入資料。

使用方法

  1. 使用StartLocalTransaction在指定的分區索引值建立一個局部事務,並擷取局部事務ID。

  2. 對局部事務範圍內的資料進行讀寫操作。

    支援對局部事務進行操作的介面為GetRow、PutRow、DeleteRow、UpdateRow、BatchWriteRow和GetRange。

  3. 使用CommitTransaction提交局部事務或者使用AbortTransaction丟棄局部事務。

注意事項

  • 主鍵自增列功能和局部事務功能不能同時使用。

  • 局部事務通過悲觀鎖(Pessimistic Lock)實現並發控制。

  • 每個局部事務從建立開始生命週期最長為60秒。

    如果超過60秒未提交局部事務或丟棄局部事務,則Table Store服務端會認為此局部事務逾時,並將局部事務丟棄。

  • 如果建立局部事務時逾時,則請求可能在Table Store服務端已執行成功,此時請等待該局部事務逾時後重新建立。

  • 未提交的局部事務可能會失效,如果出現此情況,則需要重試該局部事務內的操作。

  • 如果未對局部事務範圍內的資料進行寫操作,則提交局部事務或丟棄局部事務的操作是等同的。

  • 在局部事務中讀寫資料有如下限制:

    • 不能使用局部事務ID訪問局部事務範圍(即建立時使用的分區索引值)以外的資料。

    • 同一個局部事務中所有寫請求的分區索引值必須與建立局部事務時的分區索引值相同,讀請求則無此限制。

    • 一個局部事務同時只能用於一個請求中,在使用局部事務期間,其他使用此局部事務ID的操作均會失敗。

    • 每個局部事務中兩次讀寫操作的最大間隔為60秒。

      如果超過60秒未操作局部事務,則Table Store服務端會認為此局部事務逾時,並將局部事務丟棄。

    • 每個局部事務中寫入的資料量最大為4 MB,按正常的寫請求資料量計算規則累加。

    • 如果在局部事務中寫入了未指定版本號碼的Cell,則該Cell的版本號碼會在寫入資料時(而非提交局部事務時)由Table Store服務端自動產生,建置規則與正常寫入一個未指定版本號碼的Cell相同。

    • 如果BatchWriteRow請求中帶有局部事務ID,則此請求中所有行只能操作該局部事務ID對應的表。

    • 在使用局部事務期間,對應分區索引值的資料會被加上寫鎖,只有持有局部事務ID在局部事務範圍內的寫請求才會成功。其他非事務請求或持有其他局部事務ID在局部事務範圍內的寫請求均會失敗。在局部事務提交、丟棄或逾時後,對應的鎖也會被釋放。

    • 帶有局部事務ID的讀寫請求失敗不會影響局部事務本身的存活情況,您可以指定重試規則進行重試或者主動丟棄當前局部事務。

參數

參數

說明

TableName

資料表名稱。

PrimaryKey

資料表主鍵。

  • 建立局部事務時,只需要指定局部事務對應的分區索引值。

  • 建立局部事務後,對局部事務範圍內的資料進行讀寫操作時,需要指定完整主鍵。

TransactionId

局部事務ID,用於唯一標識一個局部事務。

建立局部事務後,操作局部事務時均需要帶上局部事務ID。

樣本

使用局部事務寫入一行資料

以下樣本用於為表的指定分區鍵建立一個局部事務後,在局部事務內寫入一行資料。

private static void transactionPutRow(SyncClient client) {
    //設定資料表名稱。
    String tableName="<TABLE_NAME>";
    //使用指定分區索引值建立一個局部事務。 
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    //設定第一個主鍵(即分區鍵)的列名、資料類型和列值。
    primaryKeyBuilder.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromString("pkvalue"));
    PrimaryKey primaryKey = primaryKeyBuilder.build();
    //構造建立局部事務的請求。
    StartLocalTransactionRequest request = new StartLocalTransactionRequest(tableName, primaryKey);
    //發起建立局部事務的請求並擷取局部事務ID。
    String txnId = client.startLocalTransaction(request).getTransactionID();
    
    //在局部事務內寫入一行資料。
    //構造行的主鍵資訊。
    PrimaryKeyBuilder primaryKeyBuilder1 = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    //設定主鍵的列名、資料類型和列值。如果表的主鍵由多個主鍵列組成,則多個主鍵列需要按照順序依次進行配置。
    primaryKeyBuilder1.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromString("pkvalue"));
    primaryKeyBuilder1.addPrimaryKeyColumn("pk2", PrimaryKeyValue.fromLong(10001));
    PrimaryKey primaryKey1 = primaryKeyBuilder1.build();
    //構造行的屬性列。
    RowPutChange rowPutChange = new RowPutChange(tableName, primaryKey1);
    //設定屬性列的列名、資料類型和列值,請根據需要添加所需屬性列。
    rowPutChange.addColumn(new Column("col1", ColumnValue.fromString("colvalue")));
    rowPutChange.addColumn(new Column("col2", ColumnValue.fromLong(10)));
    PutRowRequest request1 = new PutRowRequest(rowPutChange);
    //設定局部事務ID到請求中。
    request1.setTransactionId(txnId);
    client.putRow(request1);
    
    //提交或丟棄局部事務。 
    //提交局部事務,使局部事務中的所有資料修改生效。
    CommitTransactionRequest commitRequest = new CommitTransactionRequest(txnId);
    client.commitTransaction(commitRequest);
    //丟棄局部事務,局部事務中的所有資料修改均不會應用到原有資料。
    //AbortTransactionRequest abortRequest = new AbortTransactionRequest(txnId);
    //client.abortTransaction(abortRequest);
}

使用局部事務讀取一行資料

以下樣本用於為表的指定分區鍵建立一個局部事務後,在局部事務內讀取一行資料。

private static void transactionGetRow(SyncClient client) {
    //設定資料表名稱。
    String tableName="exampletabled";
    //使用指定分區索引值建立一個局部事務。
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    //設定第一個主鍵(即分區鍵)的列名、資料類型和列值。
    primaryKeyBuilder.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromString("111"));
    PrimaryKey primaryKey = primaryKeyBuilder.build();
    //構造建立局部事務的請求。
    StartLocalTransactionRequest request = new StartLocalTransactionRequest(tableName, primaryKey);
    //發起建立局部事務的請求並擷取局部事務ID。
    String txnId = client.startLocalTransaction(request).getTransactionID();

    //在局部事務內讀取一行資料。
    //構造行的主鍵資訊。
    PrimaryKeyBuilder primaryKeyBuilder1 = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    //設定主鍵的列名、資料類型和列值。如果表的主鍵由多個主鍵列組成,則多個主鍵列需要按照順序依次進行配置。
    primaryKeyBuilder1.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromString("111"));
    primaryKeyBuilder1.addPrimaryKeyColumn("pk2", PrimaryKeyValue.fromLong(10001));
    PrimaryKey primaryKey1 = primaryKeyBuilder1.build();
    SingleRowQueryCriteria criteria = new SingleRowQueryCriteria(tableName, primaryKey1);
    //設定讀取最新版本的資料。
    criteria.setMaxVersions(1);
    GetRowRequest request1 = new GetRowRequest(criteria);
    //設定局部事務ID到請求中。
    request1.setTransactionId(txnId);
    GetRowResponse getRowResponse = client.getRow(request1);
  
    //提交或丟棄局部事務。對於讀操作來說,提交局部事務或丟棄局部事務的操作是等同的。
    //提交局部事務,使局部事務中的所有資料修改生效。
    CommitTransactionRequest commitRequest = new CommitTransactionRequest(txnId);
    client.commitTransaction(commitRequest);
    //丟棄局部事務,局部事務中的所有資料修改均不會應用到原有資料。
    //AbortTransactionRequest abortRequest = new AbortTransactionRequest(txnId);
    //client.abortTransaction(abortRequest);
    
    //擷取並列印行資料。
    Row row = getRowResponse.getRow();
    System.out.println("讀取完畢,結果為:");
    System.out.println(row);
}

相關文檔

如果要在局部事務內進行批量寫入、範圍讀取等操作,請在建立局部事務後,使用寫入資料或者讀取資料文檔中的相應操作樣本以及在請求中帶上局部事務ID實現。