应用程序体系结构,数据位于共享网络上,服务器上没有数据库

本文关键字:网络 服务器 数据库 数据 程序体系结构 于共享 应用 共享 | 更新日期: 2023-09-27 18:28:01

我目前正在开发一个应用程序的C#项目。我们正在就用户之间共享数据的问题进行头脑风暴。我们希望能够指定一个文件夹,在那里保存应用程序的所有文件,我们希望能够将它们保存在共享文件夹(服务器,不同的PC或Mac,Nas等)

部署是这样的:

  • 在第一台电脑上安装,我们选择一个网络驱动器,共享,无论什么,并在这个位置为应用程序创建所有文件
  • 在第二台电脑上,我们安装了应用程序,并选择了相同的位置(在网络上),应用程序不会创建任何东西,它会看到它已经存在,并使用这些文件作为应用程序的数据
  • 其他客户也一样

应用程序的文件将是文档(很可能是XML格式的文档),打开应用程序时,我们希望显示所有现有文档。问题是,我们不仅希望拥有文档列表并能够编辑其内容,我们还希望能够编辑文档的属性,因此在某种程度上,我们希望有一个文件(Sqlite、XML等)来表示所有文档及其属性的列表。地址列表也是如此。

我知道所有这些看起来完全像一个带有数据库的客户端/服务器解决方案,但这个解决方案是不可能的。我第一次查看数据文件的SQLite,但我知道并发可能是一个真正的问题,并且文件锁定不能很好地工作。问题是,我在处理简单的XML文件时也会遇到同样的问题(当几个用户在工作时刷新内容,访问锁定的文件)。

所以我想我的最后一个问题是:这可行吗?有没有一个我没有看到的替代方案可以让我们更容易地做到这一点?

编辑:

好吧,我不会回复每一篇帖子或评论,因为我目前正在用SQLite测试并发性。我所做的,如果我测试的方式是错误的,请纠正我,就是启动X BackgroundWorker,它们都将在示例数据库中插入记录(每次启动应用程序时都会重新创建)。我尝试通过这些backgroundWorkers在数据库中启动100次INSERT迭代。

当然,并发是在一个应用程序运行的情况下工作的,它只是等待最后一个BackgroundWorker完成它的工作,然后编写下一条记录。我还尝试在(几乎)同一时间插入,这意味着我在每个BackgroundWorker中放入一个循环,等待模5时间戳(每5秒,每个BackgroundWorker运行一次)。同样,它正在等待上一个插入查询结束,然后再执行下一个,一切正常。我甚至在500名BackgroundWorkers中试用过,效果很好。

然后,我试着多次启动我的应用程序,并同时运行它们。在做这件事的时候,我确实遇到了一些问题。在我的应用程序的两个实例中,它仍然运行良好,但当在4-5个实例中尝试时,它真的有问题,我得到了两种类型的错误:1。数据库已锁定2。磁盘I/O故障。但是mostyle锁定了数据库。

我所做的是非常密集的,在我的应用程序场景中,永远不会有5个进程试图同时插入500个hunded行(也许我会得到两个或三个连接的并发性)。但真正困扰我的是,让我认为我的测试方法不是一个好方法,因为我在共享网络、NAS和我自己的HDD上的数据库上工作时遇到了这些错误。每次它对30-40个查询有效时,都会向我抛出"数据库已锁定"错误。

我测试错了吗?也许我不应该如此努力地让它发挥作用,但我仍然不相信SQLite不是我尝试做的事情的好选择,因为并发性将非常小。

应用程序体系结构,数据位于共享网络上,服务器上没有数据库

通过乐观/悲观锁定,您最终将尝试构建数据库。此外,在试图保持多个文件相互同步时,您会遇到一致性问题。想象一下,如果您更新了"元数据"文件,但由于网络故障,写入中途失败。文件损坏将随之而来,您将不得不尝试从备份中重建内容。

我建议几个可能的解决方案:

1) 自己托管内容,让它们成为纯粹的客户端(基于云的部署非常适合)。大多数网络/防火墙问题都可以通过使用HTTP作为传输(web服务)来规避。2) 让其中一个工作站成为"服务器",它将数据文件保存在NFS上。这将为您提供事务完整性、增量备份等。有许多优秀的嵌入式数据库管理系统可以帮助您管理这种复杂性。MS SQL Server甚至为此提供了一些不错的选择。

没错,Sqlite对数据库文件使用文件锁,所以将所有数据文件存储在数据库中会给编辑文档带来写饥饿问题。

在特定的文件级别上,自己实现简单的乐观/悲观锁定可能是更好的选择吗?例如,在使用悲观锁的情况下,如果有人已经在编辑特定的文件,你就不允许任何人编辑它。在这种情况下,你只会锁定一个文件,但不会锁定整个数据库。如果冲突(同时编辑特定文件)的可能性很低,最好使用乐观锁定。

简单乐观锁定实现:

当用户获得要读取的文件时,这是可以的,这里没有问题。如果用户获取要编辑的文件,您可以计算该文件的哈希值(或获取文件上次更新时间的时间戳),然后,当用户尝试保存编辑的文件时,比较当前(保存时)哈希值/时间戳,以确保该文件未被其他人更改。如果文件没有被更改,那么可以保存它。如果文件已经被更改,则当前用户运气不好,您需要通知他。当这种"运气不好"的可能性很低时,这种乐观的情况很好。否则,最好坚持悲观锁定,因为如果其他人在编辑文件,您甚至不允许用户启动文件编辑。