访问时替换SQLite数据库

时间:2011-04-04 08:53:11

标签: sqlite client-server

我是SQLite的新手,我打算在M2M /客户端 - 服务器环境中使用它,在服务器上生成数据库,作为文件发送到客户端并在客户端上用于数据查找。

问题是:当客户端同时使用它时,我可以替换整个数据库文件吗?

问题可能听起来很愚蠢,但客户端是Linux瘦客户端,要替换数据库文件,临时文件将重命名为到最终文件名。在Linux中,仍然打开旧版本文件的程序仍将访问旧数据,因为操作系统保留旧文件,直到所有文件句柄都已关闭。只有新的open()s才能访问该文件的新版本。

简而言之:

  • 客户端随机访问SQLite数据库
  • 从服务器接收新版本的数据库并将其写入临时文件
  • 临时文件重命名为SQLite数据库文件

我知道这是一个非常具体的问题,但也许有人可以告诉我这是否是SQLite的问题,或者在客户端运行时是否有类似的方法来替换数据库。我想要从服务器向客户端发送一堆SQL语句来更新数据库。

1 个答案:

答案 0 :(得分:1)

不,你不能只是替换一个开放的SQLite3数据库文件。除非您关闭并重新打开数据库,否则SQLite将继续使用相同的文件描述符(或Windows中的句柄)。更具体地说:

  • 删除和替换打开的文件无用(Linux)或无法使用(Windows)。 SQLite永远不会看到新文件的内容。

  • 覆盖SQLite3数据库文件是导致数据损坏的一种方法。来自SQLite3 documentation

      

    同样,如果流氓进程打开了   数据库文件或日志和写入   格式错误的数据进入其中间,   那么数据库就会腐败。

    任意覆盖DB文件的内容可能会导致一大堆问题:

    • 如果你很幸运,它只会导致数据库错误,无论如何都会迫使你重新打开数据库。
    • 根据您使用数据的方式,您的应用程序可能会崩溃并烧毁。
    • 您的应用程序可能会尝试在新文件上应用现有日记帐。听起来很痛苦?是的!
    • 如果您真的不走运,用户只会从任何查询中找回无效结果。

处理此问题的最佳方法是使用适当的客户端 - 服务器实现,其中客户端数据库文件是从来自服务器的数据更新的。从长远来看,这将允许更大的灵活性,同时通过发送更新而不是整个文件来减少带宽需求。

如果无法做到这一点,您应该以三个离散步骤更新客户端数据库文件:

  • 向客户端应用程序发送消息以关闭数据库。这允许应用程序提交任何更改,删除任何日志文件并清除其内部状态。
  • 替换/覆盖文件。
  • 向客户端应用程序发送消息以重新打开数据库。但是,您必须重新设置所有准备好的语句。

如果由于某种原因不想关闭数据库文件,那么您应该使用您的应用程序 - 甚至是单独的进程 - 使用新文件作为输入更新原始数据库文件。在这种情况下,您可能会对SQLite3 backup API感兴趣。