2017-02-27 3 views
1

私はRedshiftで複数のSQLスクリプト(1つずつ)を実行するpythonスクリプトを持っています。これらのSQLスクリプト内のテーブルのいくつかは、複数回クエリできます。例えば、表t1は1つのスクリプトで選択でき、別のスクリプトで削除/再作成できます。このプロセス全体が1つのトランザクションで実行されています。今、時々、デッドロックでエラーが検出され、トランザクション全体がロールバックされます。テーブルにデッドロックがある場合は、テーブルが解放されるのを待ってからSQL実行を再試行したいと思います。他のタイプのエラーについては、トランザクションをロールバックしたいと思います。ドキュメントから、テーブルロックはトランザクションの終了まで解放されないように見えます。私は、(トランザクションを使用して達成される)すべてのデータ変更を達成したいと思いますが、デッドロックを処理したいと思います。これがどのように成し遂げられるかについての示唆はありますか?redshiftのハンドルロック

答えて

0

リトライループを使用して、1つのトランザクションで参照しているすべてのSQLを実行します。以下は、並行処理の問題を処理して再試行するためのロジックです(簡潔にするために擬似コード)。ロックを解除するためにシステムが無期限に待機することはありません。代わりに、私は時間をかけて再試行することで、アプリケーションでそれを処理します。

begin transaction 
while not successful and count < 5 
    try 
     execute sql 
     commit 
    except 
     if error code is '40P01' or '55P03' 
      # Deadlock or lock not available 
      sleep a random time (200 ms to 1 sec) * number of retries 
     else if error code is '40001' or '25P02' 
      # "In failed sql transaction" or serialized transaction failure 
      rollback 
      sleep a random time (200 ms to 1 sec) * number of retries 
      begin transaction 
     else if error message is 'There is no active transaction' 
      sleep a random time (200 ms to 1 sec) * number of retries 
      begin transaction 
    increment count 

主要なコンポーネントは、すべてのtype of errorキャッチロールバックを必要とする場合知ること、およびexponential backoff for retriesを有するものです。

+0

私が正しく理解していれば、すべてのSQLスクリプトの後にコミットし、エラーのあるスクリプトだけをロールバックすることをお勧めします。デッドロック・エラーが発生した場合、すべてのSQLスクリプトを1つのトランザクションで確実に実行する方法はありませんか? – stech

+1

私はすべてのSQLを1つのトランザクション内で実行することを提案しています(私の 'execute sql'行)。デッドロックや失敗の場合は、すべてを再試行してください。 savepointsに興味があるかもしれませんが、自分で使ったことはありませんし、redshiftで利用可能かどうかわかりません:https://www.postgresql.org/docs/current/static/sql-savepoint.html –

+0

無視セーブポイントの使用に関する私のコメント。 redshiftでは、セーブポイントへのロールバックは利用できません:http://docs.aws.amazon.com/redshift/latest/dg/c_unsupported-postgresql-functions.html –