如何将在不同进程中完成的SQLite数据库更改通知进程?

2024-05-10 12:07:25 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有两个或多个处理SQLite数据库的进程—一个“player”进程和许多“editor”进程。

“player”进程读取数据库并更新一个视图——在我的例子中,根据存储在数据库中的事件,波形将被混合到声卡中。

“编辑器”过程是该数据库的任何编辑器:它不断更改数据库。

现在我希望播放机快速反映编辑更改。

我知道SQLite提供了钩子来跟踪同一进程中的数据库更改,但是关于如何在多个进程中执行此操作的信息似乎很少。

我可以不断地对数据库进行轮询,比较记录和触发事件,但这似乎是非常低效的,特别是当数据库增长到大容量时。

我正在考虑使用一个日志表和触发器,但我想知道是否有一个更简单的方法。


Tags: 视图数据库编辑sqlite进程过程事件编辑器
3条回答

只需在两个进程之间打开一个套接字,让编辑器告诉所有玩家关于更新的信息。

对于这一点,关系数据库并不是最佳的首选。

为什么?

你希望所有的编辑器都将更改传递给你的播放器。

你的播放器——实际上——是所有这些编辑器的服务器。你的玩家需要多个开放连接。它必须倾听所有这些连接的变化。它必须显示这些更改。

如果更改真的很大,您可以转到一个混合解决方案,其中编辑器将保留更改通知播放机。

不管怎样,编辑必须通知玩家他们有变化。这比玩家试图发现数据库中的变化要简单得多。


一个更好的设计是一个服务器,它接受来自编辑器的消息,保存它们,并通知播放器。这个服务器既不是编辑器也不是播放器,只是一个确保所有消息都被处理的代理。它接受编辑和玩家的连接。它管理数据库。

有两种实现方式。服务器就是播放器。服务器和播放器是分开的。服务器的设计没有改变——只有协议。当服务器是播放器时,服务器直接调用播放器对象。当服务器与播放机分离时,服务器将写入播放机的套接字。

当播放机是服务器的一部分时,当从编辑器接收到消息时,将直接调用播放机对象。当播放机是独立的时,一个小读取器从套接字收集消息并调用播放机对象。

播放器连接到服务器,然后等待信息流。这可以是编辑器的输入,也可以是对服务器保存在数据库中的数据的引用。

如果您的消息通信量足够小,因此网络延迟不成问题,editor会将所有数据发送到服务器/播放器。如果消息通信量太大,那么编辑器将写入数据库,并向服务器/播放机发送一条只有数据库FK的消息。


请澄清在你的问题中“如果编辑器在通知时崩溃,玩家将永远处于混乱状态”。

这听起来是一个糟糕的播放器服务设计。它不能被“永久性地搞砸”,除非它没有从不同的编辑那里得到状态。如果它是从编辑器获取状态(例如,尝试镜像该状态),那么您应该考虑这样一种设计,即播放器只是从编辑器获取状态,而不能“永久混乱”。

SQLite有一个^{}函数,它可以满足您的需要。

SQLite C Interface

Data Change Notification Callbacks

void *sqlite3_update_hook(
    sqlite3*,
    void(*)(void *,int ,char const *,char const *,sqlite3_int64),
    void*
);

The sqlite3_update_hook() interface registers a callback function with the database connection identified by the first argument to be invoked whenever a row is updated, inserted or deleted in a rowid table. Any callback set by a previous call to this function for the same database connection is overridden.

不幸的是,Python sqlite模块没有公开它。。。

下面是一个稍微有点老套的解决方法,它可以深入到C api(来自Python代码)中来利用它: https://stackoverflow.com/a/16920926

相关问题 更多 >