4

私はデータベースに比較的慣れていません。これは、経験が答えるような質問だと確信しています。

PostgreSQL で SQLAlchemy を使用しています。複数のコンピューターにまたがる複数のプロセスがさまざまなタスクを実行し、データベースを更新するシステムをセットアップしています。テストではまだトランザクションの競合に遭遇していませんが、理論的にはまだ可能です。

Google で見つけた情報によると、データベースのロックを取得するか、トランザクションを再開する準備をする必要があるようです。残念ながら、これを実際に行う方法に関する貴重な情報はほとんどありません

トランザクションを再開するには、SQLAlchemy によってスローされた例外があり、それをコードでキャッチして再試行自体を実行する必要があると思います。その例外は、一意性制約に違反した場合に SQLA がスローするものとは異なり、トランザクションの競合ではなくコードのバグを示していますか? 代わりにデータベースロックを使用したほうがよいでしょうか?

前もって感謝します!

- 編集 -

「ConcurrentModificationError」について学びました。名前は確かに私が探している例外のように聞こえます。ドキュメントによると、これはStaleDataErrorのエイリアスであり、その名前は正しいように聞こえますが、そのドキュメントはかなり不透明です。これは私が探しているエラーですか?

もう一度、どうもありがとう!

4

2 に答える 2

2

khoxsey's answer にいくつかの詳細を追加するだけです。

トランザクション分離レベルを「シリアル化可能」に設定すると、同時トランザクションが互いに干渉する場合、PostgreSQL でエラーが発生します。「シリアル化可能な」分離レベルは、同時データベース接続が多数ある場合にパフォーマンスを低下させますが、私の場合、パフォーマンスが問題にならないほど少ないです。

このシリアライゼーション レベルでトランザクションが互いに競合する場合、Postgres はそれを「シリアライゼーション エラー」と呼び、SQLSTATE エラー コードは「40001」です。現在、SQLAlchemy で SQLSTATE にアクセスするドライバー移植可能な方法はありません。ただし、psycopg2 ドライバーを使用する場合、SQLSTATE コードはexc.orig.pgcodeを介してアクセスできます。ここで、excは、 exceptステートメントによってキャッチされる例外です。

私が知る限り、例外自体は OperationalError である必要があります。

于 2012-07-26T00:15:06.710 に答える
1

私はそのエラーを見たことがありませんが、詳細はStaleModificationErrorあなたが心配している可能性があることを示唆していますが、データベース全体をロックする必要はありません. Postgres のトランザクション分離について調べて、別のトランザクションで更新されている行を別のプロセス ワーカーが知らないうちに読み取らないようにすることができます。

分離レベルを高く設定すると (read-committed など)、SA セッションは接触しているさまざまな行でロックの収集を開始します。分離レベルをどの程度厳密に設定するかを設計で決定します。リーダーが別のトランザクションがロックした行を読み取ろうとすると例外がスローされるように、十分に厳密にすることができます。その後、ロールバックするか、更新/期限切れインターフェイスを使用してその特定のセッションを更新するかを選択できます。

于 2012-07-24T04:33:03.760 に答える