Tablestore SDK for Python を使用して、1 つのパーティションキー値に対する読み取りと書き込みをアトミック操作にグループ化します。すべての書き込みがコミットされるか、すべてアボートされます。
前提条件
Tablestore SDK for Python をインストールし、クライアントを初期化します。
-
テーブルでローカル トランザクションが有効になっています。
説明既存のテーブルでローカル トランザクションを有効にする、または本機能が有効になっているかを確認するには、チケットを送信。
機能の説明
ローカル トランザクションは、1 つのパーティションキー値をスコープとし、リードコミッティド分離レベルを使用します。トランザクション内のリクエストは、トランザクション ID を共有します。ローカル トランザクションの使用方法は次のとおりです。
パーティションキー値を指定して
start_local_transactionを呼び出し、トランザクション ID を取得します。トランザクション内で
get_row、put_row、update_row、delete_row、batch_write_row、またはget_rangeを呼び出し、transaction_idに ID を渡します。commit_transactionを呼び出してすべての書き込みをコミットするか、abort_transactionを呼び出してすべての書き込みをアボートします。
def start_local_transaction(self, table_name, key)
def commit_transaction(self, transaction_id)
def abort_transaction(self, transaction_id)
次の例では、パーティションキー値 device に対してローカル トランザクションを開始し、行を書き込み、トランザクションをコミットします。
table_name = "example_table"
partition_key = [("partition", "device")]
transaction_id = client.start_local_transaction(table_name, partition_key)
primary_key = [("partition", "device"), ("id", 1)]
row = Row(primary_key, [("status", "online")])
condition = Condition(RowExistenceExpectation.IGNORE)
client.put_row(
table_name,
row,
condition,
transaction_id=transaction_id,
)
client.commit_transaction(transaction_id)
パラメーター
ローカル トランザクションには、次の主要なパラメーターが含まれます。
|
名前 |
タイプ |
説明 |
|
table_name (必須) |
|
テーブルの名前。 |
|
key (必須) |
|
ローカル トランザクションを開始するために使用されるパーティションキー。最初のプライマリキー列の名前と値のみを指定します。 |
|
primary_key (必須) |
|
トランザクション内で行を読み取りまたは書き込むために使用される完全なプライマリキー。すべてのプライマリキー列を指定します。書き込みの場合、パーティションキー値は |
|
transaction_id (必須) |
|
|
制限事項
ローカル トランザクションは、自動インクリメントプライマリキー列と互換性がありません。
ローカル トランザクションは、悲観的ロックを使用します。トランザクション中、パーティションキー値のデータに対して書き込みロックが保持され、トランザクション ID を持つ書き込みのみが成功します。
トランザクションの最大有効期間は 60 秒です。連続する 2 つの操作の間隔が 60 秒を超えると、トランザクションはタイムアウトし、サーバーはそれを破棄します。
トランザクション ID は、一度に 1 つのリクエストでのみ使用できます。同じ ID を使用する同時リクエストはすべて失敗します。
トランザクション内のすべての書き込みは、トランザクションを開始したパーティションキー値を使用する必要があります。読み取りにこの制限はありません。
単一のトランザクションで書き込めるデータは最大 4 MB です。
属性列の書き込みでデータ バージョンが指定されていない場合、サーバーはコミット時ではなく、書き込み時にバージョンを生成します。
BatchWriteRowRequestがトランザクション ID を持つ場合、すべての行は、トランザクションが開始されたテーブルを対象とする必要があります。トランザクションに書き込みが含まれていない場合、コミットとアボートは同じ効果があり、どちらもトランザクションを解放します。
トランザクション ID を指定した読み取りまたは書き込みが失敗しても、トランザクションは終了しません。リクエストを再試行するか、トランザクションを明示的にアボートしてください。
例
トランザクション内での行の読み取り
次の例では、ローカル トランザクション内で行を読み取ります。読み取り専用トランザクションの場合、コミットとアボートは同じ効果があります。
table_name = "example_table"
partition_key = [("partition", "device")]
transaction_id = client.start_local_transaction(table_name, partition_key)
primary_key = [("partition", "device"), ("id", 1)]
consumed, return_row, next_token = client.get_row(
table_name,
primary_key,
transaction_id=transaction_id,
)
print(return_row.primary_key, return_row.attribute_columns)
client.commit_transaction(transaction_id)
トランザクション内での行の一括書き込み
次の例では、set_transaction_id を呼び出して、バッチリクエストにトランザクション ID を含めます。すべての行のパーティションキー値は、トランザクションを開始するために使用された値と一致する必要があります。
table_name = "example_table"
partition_key = [("partition", "device")]
transaction_id = client.start_local_transaction(table_name, partition_key)
condition = Condition(RowExistenceExpectation.IGNORE)
row_items = [
PutRowItem(Row([("partition", "device"), ("id", 2)], [("status", "online")]), condition),
PutRowItem(Row([("partition", "device"), ("id", 3)], [("status", "offline")]), condition),
]
request = BatchWriteRowRequest()
request.add(TableInBatchWriteRowItem(table_name, row_items))
request.set_transaction_id(transaction_id)
response = client.batch_write_row(request)
if response.is_all_succeed():
client.commit_transaction(transaction_id)
else:
client.abort_transaction(transaction_id)