クエリーべき等性
最初のアプリケーションの結果を変更せずに複数回適用できるCQLクエリーは、べき等です。
最初のアプリケーションの結果を変更せずに複数回適用できるCQLクエリーは、べき等です。
UPDATE my_table SET list_col = [1] WHERE pk = 1
このクエリーは、何度実行しても、list_col
が常に値[1]
になるため、「べき等」です。
UPDATE my_table SET list_col = [1] + list_col WHERE pk = 1
list_col
が最初、空だった場合、最初の実行後は[1]
で、2回目以降は[1、1]
になるため、このクエリーは「べき等」ではありません。
デフォルトでは、すべてのDataStaxドライバーは、クエリーをべき等でないと見なします。リトライや推測的実行などの機能を活用するために、クエリーをべき等としてマークするのはユーザーの責任です。
C/C++ | C# | Java | Node.js(isIdempotent を参照) |
PHP(サポートされていません) | Python | Ruby |
べき等でない例
非確定的な関数呼び出しの結果を挿入するクエリー(たとえば、now()
およびuuid()
)は、べき等ではありません。
now()
は、要求の処理を担当するDSEコーディネーターの現在の時刻に基づいて値を生成するため、以下のクエリーは、べき等ではありません。このため、連続した呼び出しは、異なる時間に実行された場合は、異なる値を生成します。
UPDATE my_table SET v = now() WHERE pk = 1
カウンター更新は、べき等ではありません。カウンター更新の各アプリケーションは、カウンターの累積値を変更します。
UPDATE my_table SET counter_value = counter_value + 1 WHERE pk = 1;
リストへの先頭書き込み/追加書き込み、または削除の操作は、べき等ではありません。
呼び出しのたびにリストに要素を先頭書き込み/追加書き込みします。削除は、クエリーが呼び出されたときのリストの状態に応じて異なる位置の値を削除します。セット、マップ、タプル、およびユーザー定義型に対する更新、挿入、および削除の操作は、べき等であることに注意してください。
UPDATE my_table SET list_col = [1] + list_col WHERE pk = 1
直列化可能性の懸念がある場合、軽量トランザクションは非べき等と見なす必要があります。例を次に示します。
UPDATE my_table SET v = 4 WHERE k = 1 IF v = 1
このステートメントが2回実行されると、2回目の実行でIF
条件が失敗します。この場合、2回目の実行では何も行われず、v
の値は4のままです。複数のクライアントがリトライを有効にしてクエリーを実行すると、問題が発生します。
v
の値は1です。- クライアント1は上記のクエリーを実行し、1から4まで比較して設定(compare and set)操作を実行します。
- クライアント1の接続は切断されますが、クエリーは正常に完了します。
v
の値は4になります。 - クライアント2は、
v
に対して、4から2まで比較して設定(compare and set)操作を実行します。 - クライアント2のトランザクションは成功します。
v
の値は2になります。 - クライアント1は接続を失ったため、クエリーが失敗したと見なし、
v
の比較して設定(compare and set)操作を1から4まで透過的に再試行します。v
の値が2になったため、「非適用」の応答を受け取ります。
軽量トランザクションの重要な側面の1つは、直列化可能性です。列に対して、異なるクライアントからの一連の操作が同時に実行されることを考えると、正しい順序の履歴を生成するためにそれらを並べ替える方法が必要です。上記の例では、クライアントの観点から2つの操作がありました。
- クライアント1は、
v
に対して、1から4まで、適用されなかった比較して設定(compare and set)操作を実行しました。 - クライアント2は、
v
に対して、4から2まで、適用された比較して設定(compare and set)操作を実行しました。
全体的に、列は1から2に変更されました。変更を説明できる2つの操作の順序はありません。また、ステップ6での透過的なリトライによって直列化可能性が破られました。