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

Tablestore:ローカル トランザクション機能の使用

最終更新日:Dec 28, 2024

データテーブルのローカル トランザクション機能を有効にすると、指定されたパーティション キー値に基づいてローカル トランザクションを作成し、ローカル トランザクション内のデータに対して読み取りおよび書き込み操作を実行できます。ローカル トランザクション機能を使用して、1 つ以上の行を読み書きするアトミック操作を実行できます。ローカル トランザクションでは、悲観的ロックを使用して同時実行操作を制御します。

重要

Tablestore SDK for Java V5.11.0 以降を使用している場合は、データテーブルの作成時にローカル トランザクション機能を有効にできます。詳細については、データテーブルの作成を参照してください。

ローカル トランザクションを使用して、同じパーティション キーを共有するデータに対する操作がすべて成功するか、すべて失敗するかを指定できます。ローカル トランザクションの分離レベルは Read Committed です。

前提条件

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

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

手順

  1. StartLocalTransaction 操作を呼び出して、指定されたパーティション キー値に基づいてローカル トランザクションを作成し、ローカル トランザクション ID を取得します。

  2. ローカル トランザクション内のデータを読み書きします。

    GetRow、PutRow、DeleteRow、UpdateRow、BatchWriteRow、および GetRange 操作を呼び出して、ローカル トランザクション内のデータに対する操作を実行できます。

  3. CommitTransaction 操作を呼び出してローカル トランザクションをコミットするか、AbortTransaction 操作を呼び出してローカル トランザクションを中止します。

使用上の注意

  • 自動インクリメント主キー列機能とローカル トランザクション機能を同時に使用することはできません。

  • ローカル トランザクションでは、悲観的ロックを使用して同時実行操作を制御します。

  • ローカル トランザクションの有効期間は最大 60 秒です。

    ローカル トランザクションが 60 秒以内にコミットまたは中止されない場合、Tablestore サーバーはローカル トランザクションがタイムアウトしたと判断し、トランザクションを中止します。

  • タイムアウト エラーが返された場合でも、Tablestore サーバーでトランザクションが作成される場合があります。この場合、作成されたトランザクションがタイムアウトした後に、トランザクション作成リクエストを再送信できます。

  • ローカル トランザクションがコミットされていない場合、無効になる可能性があります。この場合、このトランザクションの操作を再試行してください。

  • ローカル トランザクション内のデータに対して書き込み操作が実行されない場合、コミット操作と中止操作の効果は同じです。

  • Tablestore では、ローカル トランザクション内のデータに対する読み取りおよび書き込み操作に次の制限が課せられます。

    • ローカル トランザクション ID を使用して、トランザクションの作成に使用されたパーティション キー値に基づいて指定された範囲外のデータにアクセスすることはできません。

    • 同じトランザクション内のすべての書き込みリクエストのパーティション キー値は、トランザクションの作成に使用されたパーティション キー値と同じである必要があります。この制限は、読み取りリクエストには適用されません。

    • ローカル トランザクションは、一度に 1 つのリクエストのみで使用できます。ローカル トランザクションが使用中の場合、同じローカル トランザクション ID を使用する他の操作は失敗します。

    • ローカル トランザクション内のデータに対する 2 つの連続した読み取りまたは書き込み操作の最大間隔は 60 秒です。

      ローカル トランザクション内のデータに対して 60 秒以上読み取りまたは書き込み操作が実行されない場合、Tablestore サーバーはトランザクションがタイムアウトしたと判断し、トランザクションを中止します。

    • 各トランザクションに最大 4 MB のデータを書き込むことができます。各トランザクションに書き込まれるデータ量は、通常の書き込みリクエストと同じ方法で計算されます。

    • セルにバージョン番号を指定しない場合、Tablestore サーバーは、トランザクションのコミット時ではなく、セルがトランザクションに書き込まれたときに、通常の方法でセルにバージョン番号を自動的に割り当てます。

    • 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 を含めてリクエストを開始します。