我目前正在开发一个我们想开发的应用程序的C#项目。我们正在就用户之间共享数据的问题进行头脑风暴。我们希望能够指定一个文件夹,其中应用程序的所有文件将被保存,我们希望能够将它们保存在一个共享文件夹(服务器,不同的PC或Mac,Nas等)。
部署将是这样的:
应用程序的文件将是文档(很可能是XML格式的文档),在打开应用程序时,我们希望显示所有现有文档。问题是,我们不仅希望拥有文档列表并能够编辑它们的内容,我们还希望能够编辑文档的属性,所以我们想要一个文件(Sqlite,XML,不管怎样)来表示所有文档及其属性的列表。地址列表也是一样的。
我知道与数据库解决方案完全类似的客户机/服务器,但这个解决方案是不可能的。我首先查看了SQLite的数据文件,但我知道并发性可能是一个真正的问题,而且文件锁也不能很好地工作。问题是,对于简单的XML文件,我也会遇到同样的问题(当几个用户在工作时刷新内容,访问锁定的文件)。
所以,我想我的最后一个问题是:这是可以发烧的吗?有没有其他的选择,我没有看到,这将使我们更容易做到?
编辑:
好的,我没有对每一篇文章或评论做出回应,因为我目前正在测试SQLite的并发性。我所做的,如果我测试的方式是错误的,请纠正我,就是启动X BackgroundWorker,它将全部插入一个示例数据库中的记录(每次启动应用程序时都会重新创建)。我尝试通过这些backgroundWorkers在数据库中启动100个INSERT迭代。
当然,并发正在运行一个应用程序,它只是等待最后一个BackgroundWorker完成它的工作,然后编写下一个记录。我还尝试(几乎)在同一时间插入,这意味着我在每个等待模块5时间戳的BackgroundWorker中插入一个循环(每5秒,每个BackgroundWorker运行一次)。同样,它等待上一个insert查询结束,然后再执行下一个查询,一切都正常。我甚至在500 BackgroundWorkers上试用过,效果很好。
然后我试着启动我的应用程序几次,并同时运行它们。在做这件事的时候,我确实有一些问题。对于我的应用程序的两个实例,它仍然工作正常,但是当用4-5个实例尝试时,它变得非常错误,我得到了两种类型的错误: 1.数据库被锁定了2.磁盘I/O失败。但莫斯特尔锁定了数据库。
我所做的非常密集,在我的应用程序的场景中,它永远不会出现在5个进程中,试图同时插入500个待定行(也许我会得到两个或三个连接的并发性)。但真正困扰我、让我觉得我的测试方法不太好的是,我试图在共享网络、NAS和我自己的HDD上运行数据库时,遇到了这些错误。每次它对30-40个查询起作用,然后抛出“数据库是锁定的”错误。
我测试错了吗?也许我不应该如此努力地使这个工作,但我仍然不相信SQLite不是一个好的选择,我要做的,因为并发将是非常小的。
发布于 2014-10-28 12:14:16
没错,Sqlite在数据库文件上使用文件锁,所以将所有数据文件存储在数据库中会给您的文档编辑带来写饥饿问题。
在特定的文件级别上自己实现简单的乐观/悲观锁定可能是更好的选择吗?例如,在使用悲观锁的情况下,您只是不允许任何人编辑特定的文件,如果已经有人正在编辑它。在这种情况下,您将只对一个文件进行锁定,而不是对整个数据库进行锁定。如果冲突的可能性(同时编辑特定文件)相当低,则最好采用乐观锁定。
简单的乐观锁定实现:
当用户获得文件阅读-没关系,这里没有问题。如果用户获取用于编辑的文件,则可以计算该文件的散列(或获得该文件上一次更新时间的时间戳),然后,当用户试图保存已编辑的文件时,比较当前(在保存时)散列/时间戳,以确保该文件没有被其他人更改。如果文件没有被更改,那么保存它是可以的。如果文件已经被更改,那么当前的用户是不走运的,你需要通知他。当这种“运气不好”的可能性很低时,这种乐观的情况是很好的。否则,最好坚持悲观锁定,当您不允许用户甚至开始文件编辑,如果其他人正在这样做。
发布于 2014-10-28 13:25:44
通过乐观/悲观的锁定,您最终将尝试构建一个数据库。此外,在试图保持多个文件之间的同步时,您将遇到一致性问题。想一想,如果您更新了“元数据”文件,并且由于网络闪点,写入过程中途失败。文件损坏将接踵而至,您将不得不尝试从备份中重构内容。
我想提出几个可能的解决方案:
1)自己托管内容,并让它们成为纯客户端(基于云的部署非常适合于此)。大多数网络/防火墙问题可以通过使用HTTP作为您的传输(web服务)来解决。2)有一个工作站是“服务器”,它将其数据文件保存在NFS上。这将为您提供事务完整性、增量备份等。有许多优秀的嵌入式数据库管理系统可以帮助您管理这种复杂性。甚至在这方面有一些很好的选择。
https://stackoverflow.com/questions/26605173
复制相似问题