1

単純なデータベースを持つアプリケーションを開発しています。すべての機能は正常に動作していますが、ユーザーがプログラムからデータベースを編集している場合、他のユーザーはコンテンツをすぐに見ることができません。DBGrid他のユーザーは、データが表示され、他のコンピューターからの変更で更新されるように、プログラムを閉じて再度開く必要があります。これには Delphi 7 を使用し、Firebird データベースへのアクセスには ZeosLib を使用しています。DBNavigator の更新ボタンを使用しようとしましたが、機能しません。

データベースへの接続に使用したコンポーネントは次のとおりです。

  • Zコネクション
  • ZQuery
  • 情報源
  • DBグリッド
  • DBNavigator

これは私の ZConnection と ZQuery のコードです。

object ZConnection1: TZConnection
    ControlsCodePage = cGET_ACP
    UTF8StringsAsWideField = False
    Connected = True
    Port = 3051
    Database = '192.168.254.254:test'
    User = 'test'
    Password = 'test'
    Protocol = 'firebird-2.5'
    Left = 96
    Top = 8
  end
  object ZQuery1: TZQuery
    Connection = ZConnection1
    Active = True
    SQL.Strings = (
      'select * from "test"')
    Params = <>
    Left = 128
    Top = 8
      object ZQuery1ID: TStringField
      FieldName = 'ID'
      Required = True
      Size = 8
    end
4

4 に答える 4

3

ACIDに違反しているようです。これは、SQL スタイル データベースの基本的な保証であり、すべてのデータベース更新は原子的で、一貫性があり、分離され、耐久性があり、トランザクションによって達成されます。

具体的には、一貫性と分離に問題があります。これにより、更新に複数の変更が含まれている場合でも、外部ビューアーが更新が完了する前に更新を確認できないようになります。(典型的な例は銀行振込で、ある口座からお金を引き落として別の口座に追加する必要があります。これら 2 つのアクションの一方しか表示されず、もう一方が表示されない場合は、データが正しくありません。)

トランザクションは、データベースの状態の独立したビューと考えることができます。すべてのデータベース接続には独自のトランザクションがあり、トランザクションがコミット (ファイナライズ) されるまで、その変更は他のユーザーには表示されません (分離されています)。トランザクションの分離設定によっては、トランザクションが進行中の場合、トランザクションをコミットて新しいトランザクションを開始するまで、その後も他のユーザーから見えないままになる場合があります。あなたのコードはこれを考慮していないようです。

更新をすぐに表示する必要がある場合は、トランザクションの分離モードREAD COMMITTEDであることを確認し、データベース イベントを設定して、さまざまなものが更新されたときに接続されているクライアントに通知を送信し、クライアントがデータの更新を実行できるようにする必要があります。また、分離されたデータが利用可能になるように、ユーザーの更新がすぐにコミット アクションになるようにする必要もあります。

私は ZeosLib を使用していないので、これをすべて設定する必要がある方法の詳細をすべて説明することはできませんが、正しい軌道に乗るにはこれで十分です。

于 2013-05-01T19:27:16.273 に答える
0

グリッドを表示するフォームにタイマーを追加することをお勧めします。OnTimer イベントが 1 分 (またはそれ以上) に 1 回発生するようにタイマーを設定します。この場合、クエリを閉じてから再度開きます。このようにして、全員が常に最新の情報を取得します (1 分遅れますが)。

with qWhatever do   // this is the query which is connected to the grid
 try
  disablecontrols;
  close;
  open
 finally
  enablecontrols
 end; 
于 2013-05-02T05:32:57.810 に答える
0

これをクエリの前に追加することで、この問題を解決しました。

IBDatabase1.Close;

IBDatabase1.Open;

于 2016-01-11T05:44:36.543 に答える
0

クライアントが通知を受信する必要があるマルチユーザー アプリケーションの場合、1 つのオプションは、Firebird イベントを使用して、データ変更 (SQL INSERT、UPDATE、または DELETE) ごとに「ブロードキャスト」メッセージを送信することです。

クライアントは特定のメッセージ タイプを「登録」(リッスン) することができ、Firebird サーバーがこのタイプのメッセージを送信するたびに、それを受信し、クライアント アプリケーション コードを実行します。この場合、ユーザー インターフェイス (グリッド) が更新されます。

多くの単純なユースケースではこれで十分な解決策ですが、いくつかの制限もあります。私は最近、このトピックについてここでブログを書きました:

(私は Delphi と Free Pascal のミドルウェア ライブラリの作者です)

于 2013-05-02T09:23:24.560 に答える