データ テーブルのローカル トランザクション機能を有効にすると、指定されたパーティション キー値に基づいてローカル トランザクションを作成し、ローカル トランザクション内のデータに対して読み取りおよび書き込み操作を実行できます。ローカル トランザクション機能を使用して、1 つ以上の行を読み書きするアトミック操作を実行できます。
ローカル トランザクションを使用して、同じパーティション キーを共有するデータに対する操作がすべて成功するか、すべて失敗するかを指定できます。ローカル トランザクションの分離レベルは Read Committed です。
前提条件
クライアントが初期化されていること。詳細については、「Tablestore クライアントを初期化する」をご参照ください。
ローカル トランザクション機能が有効になっているデータ テーブルが作成されていること。
説明データ テーブルを作成する際にローカル トランザクション機能を有効にしておらず、データ テーブルの作成後にローカル トランザクション機能を使用する場合は、チケットを送信してください。
ローカル トランザクション機能を使用する
start_local_transaction を使用して、指定されたパーティション キー値に基づいてローカル トランザクションを作成し、ローカル トランザクションの ID を取得します。
ローカル トランザクション内のデータを読み書きします。
GetRow、PutRow、DeleteRow、UpdateRow、BatchWriteRow、および GetRange 操作を呼び出して、ローカル トランザクション内のデータに対して操作を実行できます。
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 を含むリクエストを開始します。