1

Delphi IBQuery および IBTransaction コンポーネントを使用して、データベース内のすべてのレコードを次のクエリで更新しています。

UPDATE INVOICES SET BLK = 0;

ユーザーが別のクライアント アプリケーションを開いたままにしておくと、(ユーザーが開いた) 一部のレコードでデッドロックが発生します。

問題は、上記のクエリを完了する必要があるアプリケーションにあります。

デッドロックを強制的に取り除く何らかの解決策を実装することは可能ですか? たとえば、SQL クエリですか。

Firebird のバージョンは、Windows 7 で実行されている 2.1.2.18118 です。

4

2 に答える 2

6

最善の選択肢は、それらのアプリケーションをリファクタリングすることです。

FB/IB の自然なモードは、2 つの並列トランザクションを持つことです。

  • #1は読み取り専用で読み取りコミット済みで、閉じることはなく、データの読み取りにのみ使用されます。

  • #2は、実際に変更を適用するために短いバーストでオープン/コミットされます。「編集中」のデータは、トランザクション自体を開くことはありません。

長時間の編集トランザクションは、ガベージ コレクションをブロックし、データベース (およびインデックス) に多くの偽のデータを強制的に含めることで、データベースに影響を与えています。

IBX + IBQuery + TUpdateSQL のようなある種のカスタム更新クエリを介してこれを行うことができるかどうかはわかりませんが、bDE 時代にありました。サードパーティの FB 接続ライブラリは通常、双方向トランザクション モードをある程度サポートしています。

ただし、このアプローチでは、アプリケーションの設計方法に非常に特殊なパターンが課せられ、Firebird がデータの一貫性を保証できなくなります。これはアプリケーションの負担になります。コメントはそれについての素晴らしいリンクをもたらしました: Re: [firebird-support] Long read-only Transactions


最新の Firebird では、データベース管理者/所有者の役割を持っている場合、トランザクションを強制的に削除できます。モニタリング テーブルについてお読みください。2.5.1 にはバグがあったので、おそらく 2.5.2 のリリースを待つことに注意してください。

ただし、これらのトランザクションを強制的にロールバックすると、アプリケーションはどのように動作しますか? ユーザーはまだ編集を続けていて、変更のほとんどが失われていることに突然気付きます。

PS。http://www.sql.ru/forum/actualthread.aspx?tid=910920このコードはmon$transactions、トランザクションを接続にマップするために使用し、問題のあるアプリケーションを強制的に切断します。直接delete from mon$transactions where...が利用できない場合、それが残されたオプションになります。

PPS。FB 2.1 以来、長時間のトランザクションは数分ごとに (たとえ r/o であっても) コミット (およびクローズ) する必要があります。その理由は、トランザクションのクローズによってのみリセットされるデータベースの制御不能な成長につながる可能性のある BLOB 計算を使用した場合です。これにより、すべての db-aware コントロールの再読み取りがトリガーされる可能性がありますが、MIDAS ClientDataset のような中間キャッシュなしでトランザクションを操作すると、データベースのインフレよりも間違いなく優れており、まれに非常に高速であると報告されています。

于 2012-10-09T10:25:32.020 に答える
0

ユーザーとのやり取りを少し行うことで、問題を解決することができました。

まず、請求書のいずれかがユーザーによって編集されているかどうかを確認しています。

SELECT COUNT(*) FROM MON$RECORD_STATS WHERE MON$STAT_GROUP = 2 AND MON$RECORD_UPDATES <> 0

次に、上記のクエリの実行中にロックが見つかった場合、ユーザーに「開いているすべての請求書を閉じてください...」というメッセージを表示し、場合に備えて実行する必要があるクエリを含む failed.sqlファイルを作成します。ユーザーがアプリケーションを終了した場合。

アプリケーションの次回の起動時に、failed.sqlファイルが存在するかどうかを確認し、デッドロック チェックを使用して再度実行を試みます。

そのため、私のアプリはユーザーにとって少し煩わしいものになりましたが、ユーザーに不満をもたらす可能性のある無人操作は行われません。

于 2012-10-10T03:13:08.470 に答える