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

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

最終更新日:Dec 28, 2024

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

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

前提条件

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

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

ローカル トランザクション機能を使用する

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

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

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

  3. commit_transaction を使用してローカル トランザクションをコミットするか、abort_transaction を使用してローカル トランザクションを破棄します。

使用上の注意

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

  • ローカル トランザクションでの同時実行操作を制御するために、悲観的ロックが使用されます。

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

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

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

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

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

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

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

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

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

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

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

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

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

    • BatchWriteRow リクエストにローカル トランザクション ID が含まれている場合、リクエスト内のすべての行は、ローカル トランザクション ID に一致するテーブルにのみ書き込むことができます。

    • ローカル トランザクションを使用する場合、ローカル トランザクションが作成されたパーティションキー値のデータに書き込みロックが追加されます。ローカル トランザクション ID を含み、ローカル トランザクション内のデータの書き込みを開始する書き込みリクエストのみが成功します。他の非トランザクションリクエスト、または他のローカル トランザクションの ID を含み、ローカル トランザクション内のデータの書き込みを開始する書き込みリクエストは失敗します。トランザクションがコミットまたは中止された場合、またはトランザクションがタイムアウトした場合、ローカル トランザクション内のデータはロック解除されます。

    • ローカル トランザクション ID を持つ読み取りまたは書き込みリクエストが拒否された場合でも、ローカル トランザクションは有効なままです。再試行ルールを指定してリクエストを再送信するか、トランザクションを中止することができます。

パラメーター

パラメーター

説明

table_name

データテーブルの名前。

key

データテーブルのパーティションキー。

ローカル トランザクションを作成するときは、パーティションキー値を指定する必要があります。

primary_key

データテーブルの主キー。

ローカル トランザクションでデータを読み書きするときは、すべての主キー列の値を指定する必要があります。

transaction_id

ローカル トランザクションを一意に識別するローカル トランザクション ID。

ローカル トランザクションでデータを読み書きするときは、ローカル トランザクション ID を指定する必要があります。

ローカル トランザクション機能を使用してデータの行を書き込む

次のサンプルコードは、テーブル内の指定されたパーティションキー値に基づいてローカル トランザクションを作成し、ローカル トランザクションにデータの行を書き込む方法の例を示しています。ローカル トランザクションにデータの行が書き込まれた場合は、トランザクションをコミットします。そうでない場合は、トランザクションを破棄します。

def  transaction_put_row(client):
    # データテーブルの名前を指定します。
    table_name = '<TABLE_NAME>'
    # パーティションキー PK0 に基づいてローカル トランザクションを作成します。
    key = [('PK0', 1)]
    # start_local_transaction メソッドの戻り値はトランザクション ID です。
    transaction_id = client.start_local_transaction(table_name, key)

    # データを書き込みます。
    primary_key = [('PK0', 1), ('PK1', 'transaction')]
    attribute_columns = [('value', 'origion value')]
    row = Row(primary_key, attribute_columns)
    condition = Condition(RowExistenceExpectation.IGNORE)
    try:
        # put_row メソッドを呼び出すときに ReturnType パラメーターを指定しない場合、return_row パラメーターの値は None です。
        consumed, return_row = client.put_row(table_name, row, condition, None, transaction_id)
        # リクエストによって消費される書き込み CU の数を表示します。
        print('put row succeed, consume %s write cu.' % consumed.write)
        # ローカル トランザクションにデータの行が書き込まれた場合は、ローカル トランザクションをコミットします。この場合、ローカル トランザクション内のすべてのデータ変更が有効になります。ローカル トランザクションを破棄して、ローカル トランザクション内のすべてのデータ変更を無効にすることができます。
        client.commit_transaction(transaction_id)
    # ほとんどの場合、クライアント例外はパラメーターエラーまたはネットワーク例外によって発生します。
    except OTSClientError as e:
        print("put row failed, http_status:%d, error_message:%s" % (e.get_http_status(), e.get_error_message()))
        # ローカル トランザクションにデータの行を書き込めなかった場合は、ローカル トランザクションを破棄します。この場合、ローカル トランザクション内のすべてのデータ変更は、データテーブル内のデータに反映されません。
        client.abort_transaction(transaction_id)
    # ほとんどの場合、サーバー例外はパラメーターエラーまたはスロットリングエラーによって発生します。
    except OTSServiceError as e:
        print("put row failed, http_status:%d, error_code:%s, error_message:%s, request_id:%s" % (e.get_http_status(), e.get_error_code(), e.get_error_message(), e.get_request_id())) 
        # ローカル トランザクションにデータの行を書き込めなかった場合は、ローカル トランザクションを破棄します。この場合、ローカル トランザクション内のすべてのデータ変更は、データテーブル内のデータに反映されません。
        client.abort_transaction(transaction_id)

ローカル トランザクション機能を使用してデータの行を読み取る

次のサンプルコードは、テーブル内の指定されたパーティションキー値に基づいてローカル トランザクションを作成し、ローカル トランザクションでデータの行を読み取る方法の例を示しています。

def transaction_get_row(client):
    # データテーブルの名前を指定します。
    table_name ='<TABLE_NAME>'
    # パーティションキー PK0 に基づいてローカル トランザクションを作成します。
    key = [('PK0', 1)]
    # start_local_transaction メソッドの戻り値はトランザクション ID です。
    transaction_id = client.start_local_transaction(table_name, key)
    
    # データを読み取ります。
    primary_key = [('PK0', 1), ('PK1', 'transaction')]
    columns_to_get = ['value']
    consumed, return_row, next_token = client.get_row(
        table_name, primary_key, columns_to_get, None, 1, None, None, None, None, transaction_id
    )
    for att in return_row.attribute_columns:
        print ('\tname:%s\tvalue:%s' % (att[0], att[1]))

    # ローカル トランザクションをコミットまたは破棄します。ローカル トランザクションをコミットまたは破棄したときの読み取り操作への影響は同じです。
    # ローカル トランザクションをコミットして、ローカル トランザクション内のすべてのデータ変更を有効にします。
    client.commit_transaction(transaction_id)
    # ローカル トランザクションを破棄します。この場合、ローカル トランザクション内のすべてのデータ変更は、データテーブル内のデータに反映されません。
    #client.abort_transaction(transaction_id)

参照

複数のデータ行を同時に書き込む場合、または主キー値が特定の範囲内にあるデータを読み取る場合は、ローカル トランザクションを作成します。次に、データの書き込み または データの読み取り トピックに記載されているサンプルコードを参照して、ローカル トランザクション ID を含むリクエストを開始します。