这不是查询。它总结了我们解决SQL Compact数据库文件中的损坏问题的解决方案,几乎取得了一定的成功。 SQLCE腐败是一个非常普遍的问题。我们从StackOverflow的早期帖子中获得了巨大的帮助,因此这篇文章。
我们的产品是一个3层架构,服务器作为Windows服务运行,通过.Net Remoting连接到Rich Clients。我们的产品自2006年起使用SQLCE。我们已从v3.1升级到v3.5,现在升级到v4.0。我们为一些非常具体的要求提供了自定义OR映射工具。我们遇到了v3.1的有限问题,我们在v3.5和v4.0上遇到了更多问题。
最初使用v3.5,我们实施了SqlCeEngine.Repair
。但它只会丢弃损坏的数据,并尝试重新创建一个稳定的数据库。我们发现受影响的桌子的外键丢失了。我们必须立即废除这一点。我们开始向用户通知数据库损坏,并恢复上次备份。这只能暂时缓解;腐败的问题依然存在。
今年,我们采用了v4.0。但是,我们的应用程序还引入了几个新功能,极大地增加了数据库调用的数量。 v4.0开始很好,但在软件使用量增加时开始出现问题。应用程序运行时发生的损坏不会导致Windows崩溃,异常关闭或磁盘问题。数据库刚刚损坏。
下一篇文章介绍了我们为此问题设计的解决方案:
答案 0 :(得分:17)
[分离查询和解决方案]
以下是我们解决问题的方法:
A)关闭/处置连接/命令/交易对象: 我们确保没有未使用的,未关闭的连接,事务或命令对象。我们的ORM工具用于在事务上调用commit之后创建新对象,在某些情况下它们处于空闲状态。这大大减少了50%的腐败数量。
B)禁用自动收缩: 在应用程序运行过程中发生的唯一一个程序是Auto-Shrink,我们无法控制它。我们在应用程序启动时调用了SqlCeEngine.Compact。我们决定废除压缩和自动收缩。令我们惊讶的是,我们将腐败率再降低了48%。这是在黑暗中拍摄的,我们无法相信Auto-Shrinking可能会导致这样的问题。我们几乎解决了更新的问题。
C)同步数据库事务: 一些数据库损坏仍在发生。由于没有检测到明确的原因,我们决定同步数据库事务!我知道很多数据库人都不会喜欢这个。我也不喜欢它。我们在中间层引入了锁,以确保一次只有一个调用正在修改数据库。我们最大的实施是55个客户同时使用我们的系统。同步数据库调用几乎不会导致任何可见的性能延迟。相反,Synchronizing允许我们定期实现对SqlCeEngine.Compact的定时器驱动调用。我们知道Compact不是罪魁祸首,我们认为Compaction是一个必要的调用,因为它重新索引数据库(我们的解决方案会进行大量的插入和删除)。但是,它需要专门运作;调用Compact时没有数据库调用。同步允许我们在应用程序运行期间控制它。由于我们已经这样做了,我们没有收到单个数据库损坏问题。现在已经一个多月了。从一周内差不多5个客户到一个月零。
引导我们思考B和C的基本原因是SQLCE是一个嵌入式数据库。每个嵌入式数据库解决方案都会出现损坏。全面的数据库解决方案独立工作,由24x7数据库服务器支持,管理连接和其他任务。嵌入式数据库系统没有这样的支持系统。它活着的唯一阶段是连接打开时。
更多指针:1)我们使用CommitMode.Immediate实现提交,这使得Flush-Interval属性变得多余。 2)AutoShrink设置为100,完全禁用该过程3)我增加了连接超时,以使同步数据库调用顺利运行。 4)应用程序启动时调用Compact。如果客户端根本没有关闭他们的机器,我们实施了计时器,每24小时调用一次Compact。
希望这篇文章有助于解决问题。
答案 1 :(得分:5)
如果使用SQL Server CE 4.0,则存在可能阻止数据刷新到磁盘(AT ALL)的已知问题。 https://support.microsoft.com/en-us/kb/2979868和修补程序https://support.microsoft.com/en-us/kb/2960153
用他们自己的话说:
假设在Microsoft SQL Server Compact 4.0中将已提交的事务刷新到磁盘之前,已在连接字符串中指定了最大秒数的刷新间隔。在这种情况下,提交的事务可能比刷新间隔要花费更长的时间才能刷新到磁盘,甚至可能不会刷新到磁盘。此外,如果程序异常终止,则会发生数据丢失。
解决此问题的修补程序包含在SQL Server Compact 4.0 Service Pack 1的按需修补程序更新程序包中。
提供的解决方法是在您要确保刷新的块周围使用transaction.Commit(CommitMode.Immediate)