「ERROR: 1023 DETAIL: Serializable isolation violation on table in Redshift」(エラー: 1023 詳細: Redshift のテーブルでの直列化可能分離違反) エラーを解決するにはどうすればよいですか?

最終更新日: 2022 年 2 月 18 日

異なるセッション内で Amazon Redshift の複数のオペレーションを同時に実行すると「ERROR: 1023 DETAIL: Serializable isolation violation on table in Redshift」(エラー: 1023 詳細: Redshift のテーブルでの直列化可能分離違反) というメッセージが表示されます。 このエラーの解決方法を教えてください。

簡単な説明

Amazon Redshift の同時書き込みオペレーションは、直列化可能でなければなりません。すなわち、トランザクションは、同時に実行された場合と同じ結果を出せる 1 つ以上の順序で、直列的に実行可能でなければなりません。詳細については、「直列化可能分離」を参照してください。

直列化可能分離のエラーを解消するには、次のいずれか 1 つまたは両方の方法を使用します。

  • 原子性のために同じトランザクションに存在している必要がないオペレーションをトランザクションの外部に移動させる
  • 各セッションですべてのテーブルをロックして強制的に直列化する

解決方法

原子性のために同じトランザクションに存在している必要がないオペレーションをトランザクションの外部に移動させる

2 つのトランザクション内にある各オペレーションが、他方のトランザクションの結果に影響を与え得る方法で相互参照している場合は、この方法を使用します。例えば、2 つのセッションが個々にトランザクションを開始したとします。

Session1_Redshift = # BEGIN;
Session2_Redshift = # BEGIN;

各トランザクションの SELECT ステートメントの結果は、他方のトランザクションの INSERT ステートメントの影響を受ける可能性があります。任意の順序で直列に実行した場合、一方の SELECT ステートメントの結果は、同時実行した場合よりも常に 1 行多く行を返します。オペレーションを並列に実行した場合と同じ結果を生成する、直列に実行できる順序が存在しないため、実行した最後のオペレーションで直列化可能分離エラーが発生します。

Session1_redshift=# select * from tab1;
Session1_redshift =# insert into tab2 values (1);
Session2_redshift =# insert into tab1 values (1);
Session2_redshift =# select * from tab2;

SELECT ステートメントの結果が重要ではない (すなわち、トランザクション内のオペレーションの原子性が重要ではない) 場合は、SELECT ステートメントをトランザクションの外部に移動させます。例:

Session1_Redshift=# BEGIN;
Session1_Redshift = # insert into tab1 values (1)
Session1_Redshift = # END;
Session1_Redshift # select * from tab2;
Session2_Redshift # select * from tab1;
Session2_Redshift =# BEGIN;
Session2_Redshift = # insert into tab2 values (1)
Session2_Redshift = # END;

この例では、トランザクションの相互参照は行われていません。2 つの INSERT ステートメントには互いに影響し合っていません。オペレーションを並列に実行した場合と同じ結果を生成する、直列に実行できる順序が 1 つ以上存在するので、このトランザクションは直列化可能です。

各セッションですべてのテーブルをロックして強制的に直列化する

LOCK コマンドが、直列化可能分離エラーが発生するオペレーションをブロックします。LOCK コマンドを使用するときは、必ず次の手順に従います。

  • トランザクションの影響を受けるテーブルを、トランザクション内の読み取り専用の SELECT ステートメントの影響を受けるものも含め、すべてロックします。
  • オペレーションの実行順序に関係なく、同じ順序でテーブルをロックします。
  • オペレーションを実行する前に、トランザクションの開始時にすべてのテーブルをロックします。

この記事はお役に立ちましたか?


請求に関するサポートまたは技術サポートが必要ですか?