1

我正在开发一个具有简单数据库的应用程序。所有功能都运行良好,但是当用户从程序中编辑数据库时,其他用户无法立即看到内容。另一个用户需要关闭程序并重新打开它以显示数据并DBGrid使用来自其他计算机的这些更改进行更新。为此,我使用 Delphi 7 和 ZeosLib 来访问我的 Firebird 数据库。我尝试使用 DBNavigator 上的刷新按钮,但它不起作用。

我用来连接数据库的组件是:

  • ZConnection
  • 查询
  • 数据源
  • 数据库网格
  • 数据库导航器

这是我的 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 风格数据库的基本保证,所有数据库更新都是原子的、一致的、隔离的和持久的,并且通过事务完成。

具体来说,您在一致性和隔离方面遇到了问题,这确保外部查看者在更新完成之前永远不会看到更新,即使该更新包含多个更改。(典型的例子是银行转账,需要从一个账户中减去钱,然后将其添加到另一个账户中。如果您只看到这两个操作之一,而没有看到另一个,则您的数据不正确。)

您可以将事务视为数据库状态的独立视图。每个数据库连接都有自己的事务,并且它所做的任何更改对其他任何人(隔离)都是不可见的,直到他们提交(最终确定)事务。根据事务的隔离设置,即使在此之后,如果他们有正在进行的事务,它们可能对其他用户仍然不可见,直到他们提交事务并开始新的事务。听起来您的代码没有考虑到这一点。

如果您需要立即看到更新,则需要确保事务的隔离模式READ COMMITTED,并设置数据库事件以在各种更新时向连接的客户端发送通知,以便客户端可以执行其数据的刷新。您还需要确保用户更新立即导致提交操作,以便隔离数据可用。

由于我不使用 ZeosLib,我无法解释您需要如何设置这一切的所有细节,但这足以让您走上正轨。

于 2013-05-01T19:27:16.273 回答
0

我建议您在显示网格的表单中添加一个计时器。设置计时器,使其每分钟(或更长时间)触发一次 OnTimer 事件。在这种情况下,请关闭查询然后重新打开它。这样,每个人都能获得最新信息(尽管晚了一分钟)。

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

对于客户端需要接收通知的多用户应用程序,一种选择是使用Firebird 事件为每次数据更改(SQL INSERT、UPDATE 或 DELETE)发送“广播”消息。

客户端可以“注册”(侦听)特定消息类型,并且每当 Firebird 服务器发送具有此类型的消息时,它们都会接收它,并运行客户端应用程序代码,在您的情况下,这将刷新用户界面(网格)。

虽然这在许多简单的用例中可能是一个足够的解决方案,但也有一些限制。我最近在这里写了关于这个主题的博客:

(我是 Delphi 和 Free Pascal 中间件库的作者)

于 2013-05-02T09:23:24.560 回答
0

我通过在查询之前添加这个来解决这个问题。

IBDatabase1.关闭;

IBDatabase1.打开;

于 2016-01-11T05:44:36.543 回答