2014-10-28 46 views
0

我目前正在开发一个我们想要开发的应用程序的C#项目。我们正在就用户之间共享数据的问题进行头脑风暴。我们希望能够指定一个文件夹,其中应用程序的所有文件将被保存,并且我们希望能够将它们保存在共享文件夹(服务器,不同的PC或Mac,Nas等)上。 )。在服务器上没有数据库的共享网络上的数据应用程序体系结构

部署会像这样:第一台PC上

  • 安装,我们选择一个网络驱动器,共享,任何创造的所有文件在此位置的应用程序。
  • 在我们安装的应用程序,我们选择了相同的位置(在网络上)的第二台PC,应用程序不会产生任何东西,它认为它已经存在,它使用这些文件作为应用程序的数据
  • 同在其他客户端上的东西

应用程序的文件将成为文档(最有可能的XML格式的文档),当打开应用程序时,我们要显示所有现有的文档。问题是,我们不仅希望获得文档列表并能够编辑它们的内容,还希望能够编辑文档的属性,所以我们想要一个文件(Sqlite, XML,无论什么)表示所有文档及其属性的列表。地址列表同样的东西。

我知道所有与数据库解决方案完全一样的客户端/服务器,但这种解决方案是不可能的。我首先在查看数据文件的SQLite,但我知道并发性可能是一个真正的问题,并且文件锁定效果不佳。问题是,我会遇到与简单的XML文件相同的问题(在多个用户正在工作时刷新内容,访问锁定的文件)。

所以我想我最后的问题是:它是否可行?有没有其他方法可以让我们更轻松地做到这一点?

编辑:

好的,我不回应每一个岗位或评论,因为我目前使用SQLite测试并发。我做了什么,如果我测试这种方式是错误的,请纠正我,是启动X BackgroundWorker,它们都将在示例数据库中插入记录(每次启动应用程序时都会重新创建)。我尝试通过这些背景工作者在数据库中启动100次INSERT迭代。

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

然后我尝试多次启动我的应用程序并同时运行它们。当我这样做时,确实有一些问题。有两个我的应用程序的实例仍然正常工作,但是当它用4-5个实例进行尝试时,它确实有问题,并且出现了两种类型的错误:1.数据库被锁定2.磁盘I/O故障。但是大多数锁定的数据库。

我做的事情非常密集,在我的应用程序的场景中,它永远不会遇到5个进程,试图同时插入500个hunded行(也许我会得到两个或三个连接的并发)。但是真正困扰我的是什么让我认为我的测试方法不是一个好的方法,那就是我遇到了这些错误,试图在共享网络上,NAS上以及我自己的硬盘上工作。每次它可能为30-40查询工作,然后扔我“数据库被锁定”的错误。

我测试它错了吗?也许我不应该这么努力地完成这项工作,但我仍然不相信SQLite不是我想要做的很好的选择,因为并发将会非常小。

+0

为什么你不能使用数据库服务器? – Maarten 2014-10-28 09:55:38

+0

从你的问题来看,似乎你想对原始XML文件有类似数据库的数据访问。你能解释为什么一个数据库是不可能的吗?我只能猜测,但你知道你可以将XML文件存储在数据库中吗? – DMAN 2014-10-28 09:55:40

+0

我们针对的是非常小的客户(大部分时间没有服务器,只有外部硬盘或Nas),我们希望能够在一台PC上使用该应用程序或在多台PC上共享数据,但项目不包括开发服务器版本。我们也想提出一个完整的试用版本,这并不适合客户/服务器解决方案。最后一件事:我们与客户端/服务器应用程序建立了合作伙伴关系,我们每天都会在这些架构中看到许多问题(访问权限,防火墙等)。我们不希望这样。 – 2014-10-28 10:07:52

回答

1

你说得对,Sqlite在数据库文件上使用文件锁,所以将所有数据文件存储到数据库中会带来编写文档的写缺陷问题。

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

简单的乐观锁定实现:

当用户获取阅读文件 - 没关系,这里没有问题。如果用户获取文件进行编辑,您可以计算该文件的散列(或获取文件上次更新时间的时间戳),然后当用户尝试保存编辑文件时,比较当前(保存时)散列/时间戳以确保该文件没有被其他人更改。如果文件没有被更改,那么可以保存它。 IF文件已被更改,则当前用户运气不佳,您需要通知他。当这种“不幸”的可能性非常低时,这种乐观的情况很不错。否则,最好坚持悲观锁定,当你不允许用户开始文件编辑时,如果有人正在做这件事。

+0

在“单个文件”的基础上,我明白你的意思,我认为这是要走的路。尽管如此,我仍然必须允许读取锁定文件。但我不知道在网络共享上实现文件锁定是否容易......但是关于我的文档“列表”,我仍然可以使用Sqlite,但在自己的应用程序中实现一层锁定吗?用户可以随时阅读列表,如果他试图编辑它,它会检查它是否被锁定,如果不是,它会检查用户是否未改变其他用户所做的更改(并在以下情况下警告用户),如果没有问题锁定文件,写入并解锁。好像? – 2014-10-28 13:11:00

+0

如果我正确理解你,你正在谈论乐观锁定情况,我刚刚更新了答案。而且,是的,我认为您可以使用Sqlite不仅用于存储“文件列表”,还可用于存储有关文件锁定的信息,文件最后更新时间等,以管理并发修改。 – ialekseev 2014-10-28 13:59:40

1

随着你的乐观/悲观锁定,你最终试图建立一个数据库。另外,在尝试保持多个文件彼此同步时,您会遇到一致性问题。考虑是否更新“元数据”文件,并且由于网络信号而导致写入中途失败。随后会发生文件损坏,并且您将继续尝试从备份中重新构建。

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

1)主机的内容自己,并让他们成为纯粹的客户端(基于云的部署是非常理想的)。大多数网络/防火墙问题可以通过使用HTTP作为传输(Web服务)来绕过。 2)有一个工作站是“服务器”,它将数据文件保存在NFS上。这将为您提供事务完整性,增量备份等。有良好的嵌入式数据库管理系统批次可帮助您管理这种复杂性。 MS SQL Server甚至有一些很好的选择。

+0

感谢您的回答,我的一部分对此SQLite解决方案只想说“不”。我听到你在说什么,但我仍然试着尽可能最好地测试SQLite,看看它是否可以工作(你可以看到我编辑了我的第一篇文章) – 2014-10-30 10:09:47

+0

但是关于你的两个解决方案,我会非常乐意使用第一个,但我们知道我们的客户和他们的隐私,说服他们把他们的数据放在局域网之外的服务器上可能很困难。对于你的第二个解决方案,你会说我仍然在做一个clienz/server应用程序,只保存Nas上的数据文件(而不是数据库),例如? – 2014-10-30 10:21:12

+1

这似乎是一个非常合理的解决方案。顺便说一句,我发现后,快速谷歌搜索:http://beets.radbox.org/blog/sqlite-nightmare.html似乎很可能你有与SQLLite相同的问题,它看起来像它可以通过重新编译用一个标志来启用毫秒超时... – 2014-10-30 13:11:15

相关问题