从 SQLite 接收 .NET 中的数据库更新事件
我最近发现了 SQLite 的强大之处,特别是 SQLite 的 .NET 包装器,位于 http://sqlite.phxsoftware.com /。
现在,假设我正在开发将在同一网络上的多台计算机上运行的软件。没什么疯狂的,可能只有 5 或 6 台机器。每个软件实例都将访问存储在共享目录中的文件中的 SQLite 数据库(这是一个坏主意吗?如果是这样,请告诉我!)。
如果一个实例更新数据库文件,是否有一种方法可以通知应用程序的每个实例?一种明显的方法是使用 FileSystemWatcher 类,将整个数据库读入 DataSet,然后...你知道...枚举整个内容以查看新内容...但是是的,实际上这看起来相当愚蠢。有 SQLite 更新提供者这样的东西吗?
这作为一个问题有意义吗?当谈到 ADO.NET 时,我也几乎是一个新手,所以我可能从完全错误的角度来处理这个问题。
I've recently discovered the awesomeness of SQLite, specifically the .NET wrapper for SQLite at http://sqlite.phxsoftware.com/.
Now, suppose I'm developing software that will be running on multiple machines on the same network. Nothing crazy, probably only 5 or 6 machines. And each of these instances of the software will be accessing an SQLite database stored in a file in a shared directory (is this a bad idea? If so, tell me!).
Is there a way for each instance of the app to be notifiied if one instance updates the database file? One obvious way would be to use the FileSystemWatcher
class, read the entire database into a DataSet, and then ... you know ... enumerate through the entire thing to see what's new ... but yeah, that seems pretty idiotic, actually. Is there such a thing as a provider of SQLite updates?
Does this even make sense as a question? I'm also pretty much a newbie when it comes to ADO.NET, so I might be approaching the problem from the entirely wrong angle.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
通过网络使用 SQLite 并不是一个好主意。 此处查看 SQLite 自己的建议。
客户端-服务器数据库将更加可靠,并且还可以解决您的通知问题。例如,PostgreSQL 通过 NOTIFY 和 LISTEN 语句具有客户端间信号机制,可以直接从客户端或从函数、存储过程或触发器内部使用。
即使您决定使用 SQLite,也不要使用文件监视 API。由于文件系统内部深处的竞争条件,它们在 Windows 上完全被破坏。来自 FileSystemWatcher 的 MSDN 条目:
它提供了缓解这种情况的建议,但没有一个提供任何可靠性保证。
Using SQLite across a network isn't a good idea. Check out SQLite's own recommendations on this here.
A client-server database will be far more reliable and may also solve your notification problem. For instance, PostgreSQL has an inter-client signalling mechanism via the NOTIFY and LISTEN statements, which can be used directly from a client or from inside a function, sproc or trigger.
Even if you decide to go for SQLite, do not use file-watching APIs. They are completely broken on Windows due to a race-condition deep in the bowels of the filesystem. From the MSDN entry for FileSystemWatcher:
It offers recommendations to alleviate this, but none of them provides any relibility guarantees.
虽然没有任何内置机制可以挂钩某种更改事件,但您可以跨多个进程检测 SQLite 数据库中的更改。
SQLite 数据库不应通过网络共享进行共享,原因有多种,创建者在此进行了解释:https:// /www.sqlite.org/useovernet.html
如果您有一台运行 TCP 客户端服务器应用程序的服务器来接收您的请求并发送数据作为响应,那么它会更加高效和一致。
轮询文件头
SQLite 文件头包含字段 文件更改计数器,该字段每当数据库或其表已被修改。我们可以在标头上使用轮询来检测更改。我不知道为什么这么多人反对轮询,这在低级编程中是完全正常的,如果软件或硬件不提供任何中断,无论如何你都会陷入轮询。
SQLiteHeader struct
SQLiteHeaderParser 类
SQLiteHeaderError 枚举
SQLiteChangeMonitor 类
高频轮询
SQLiteChangeMonitor
类使用默认轮询间隔为 1000 毫秒 (1 秒)。对于高频轮询间隔,我建议使用此答案中描述的模式: https://stackoverflow.com/a/23341005/22191764缺点得多
这不提供任何有关修改内容的信息,但轮询标头然后更新数据库视图然后始终对数据库运行查询并最终更新仍然要高效 你的观点。
While there isn't any built-in mechanism to hook into some sort of change event you can detect changes in a SQLite database across multiple processes.
A SQLite database should not be shared over a network share for multiple reasons as explained by the creators here: https://www.sqlite.org/useovernet.html
It is far more efficient and consistent if you have a server running a TCP client server app that receives your requests and sends the data as a response.
Polling the file header
The SQLite file header contains the field File change counter which gets updated whenever the database or its tables have been modified. We can use polling on the header to detect changes. I don't know why so many people are against polling, it is perfectly normal in low-level programming and if a software or hardware does not provide any interrupt you are stuck with polling anyway.
SQLiteHeader struct
SQLiteHeaderParser class
SQLiteHeaderError enum
SQLiteChangeMonitor class
High frequency polling
The
SQLiteChangeMonitor
class uses a default polling interval of 1000ms (1s). For high frequency polling intervals I'd recommend a pattern as described in this answer: https://stackoverflow.com/a/23341005/22191764Drawbacks
This does not provide any information about what has been modified but it is still far more efficient to poll the header and then update your DB views then always running queries against your DB and eventually updating your view.