我目前正在开发一个我们想要开发的应用程序的C#项目。我们就在用户之间共享数据的问题进行头脑风暴。我们希望能够指定一个文件夹,其中将保存应用程序的所有文件,并且我们希望能够将它们保存在共享文件夹(服务器,不同的PC或Mac, Nas等)。
部署就像这样:
应用程序的文件将成为文档(很可能是XML格式的文档),在打开应用程序时,我们要显示所有现有文档。问题是,我们不仅希望拥有文档列表并能够编辑其内容,我们也希望能够编辑文档的属性,因此在某种程度上我们可以#39 ; d喜欢表示所有文档及其属性列表的文件(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个行(也许我会得到两个或三个并发连接)。但真正让我烦恼的是什么让我认为我的测试方法并不是一个好的方法,就是我在共享网络,NAS和我自己的硬盘上尝试使用数据库时遇到了这些错误。每次它可能工作30-40个查询然后扔我"数据库被锁定"错误。
我测试错了吗?也许我不应该如此努力地完成这项工作,但我仍然不相信SQLite不是我试图做的好的替代方案,因为并发性将是真的很小。
答案 0 :(得分:1)
你没错,Sqlite在数据库文件上使用文件锁,因此将所有数据文件存储在数据库中会给编辑文档带来写入饥饿问题。
在特定文件级别上自己实现简单的乐观/悲观锁定可能是更好的选择吗?例如,在使用悲观锁定的情况下,如果某人已经在编辑它,那么您就不允许任何人编辑特定文件。在这种情况下,您将仅在一个文件上保持锁定,但不在整个数据库上保持锁定。如果冲突的可能性(同时编辑特定文件)非常低,那么最好采用乐观锁定。
简单乐观锁定实现:
当用户获取文件进行阅读时 - 没关系,这里没问题。如果用户获取文件进行编辑,您可以计算此文件的哈希值(或获取文件上次更新时间的时间戳),然后,当用户尝试保存已编辑文件时,比较当前(保存时)哈希/时间戳确保该文件未被其他人更改。如果文件尚未更改,则可以保存。 IF文件已被更改,那么当前用户运气不好,您需要通知他。当这种“失败”的可能性非常低时,这种乐观的情况很好。否则,最好坚持使用悲观锁定,当你不允许用户甚至开始进行文件编辑时,如果其他人正在这样做的话。
答案 1 :(得分:1)
通过乐观/悲观锁定,您最终会尝试构建数据库。此外,在尝试保持多个文件彼此同步时,您将遇到一致性问题。想想你是否更新了'#34;元数据"文件,由于网络短信,写入失败了一半。文件损坏将随之发生,您将不得不尝试从备份中重建内容。
我会建议一些可能的解决方案:
1)托管内容,让它们成为纯粹的客户端(基于云的部署是理想的选择)。使用HTTP作为传输(Web服务)可以避免大多数网络/防火墙问题。 2)让其中一个工作站成为"服务器",它将数据文件保存在NFS上。这将为您提供事务完整性,增量备份等。很多良好的嵌入式数据库管理系统可帮助您管理这种复杂性。 MS SQL Server甚至有一些很好的选择。