【问题标题】:Should I put my faith in SQLite transactions to avoid file corruption?我应该相信 SQLite 事务以避免文件损坏吗?
【发布时间】:2010-01-05 21:20:49
【问题描述】:

短版

如果我的进程在事务中间终止,或者在 SQLite 提交事务时,数据库文件损坏的可能性有多大?

加长版

我的应用程序使用 SQLite 数据库进行存储(直接,而不是通过 Core Data)。我正在开发一个新版本的应用程序,它需要更新数据库模式。启动时,应用程序将检查数据库,如果需要更新,则执行一系列 SQL 语句。

根据数据库中的数据量,更新可能会长时间运行(以秒为单位),所以我需要考虑在更新完成之前进程可能被终止的可能性。 (对于上下文,这在 iPhone 上,处理器很慢,应用程序可能会因来电而终止。)当然,我会将升级 SQL 语句包装在事务中。这足以保证数据库不会损坏吗?

我假设事务按照宣传的方式工作,并且如果进程在事务中间终止,则文件将正常。但我也假设在 COMMIT 期间有一个时间窗口可能会出错。

为了安全起见,我可以在开始更新之前创建数据库文件的备份副本,但如果事务是安全的,那么这将是矫枉过正。它还会使更新过程花费更长的时间,这增加了它被中断的机会,然后我不得不考虑文件复制操作可能会被中断......我想保持代码尽可能简单(但并不简单)。

在研究这个问题的过程中,我开始阅读“Atomic Commit In SQLite”,这比我可能需要知道的更详细,但让我相信我不需要事后猜测 SQLite 的能力保护数据库文件。但我仍然希望听到 Stack Overflow 的消息:交易是否足够好,还是我应该更加谨慎?

【问题讨论】:

    标签: iphone transactions sqlite


    【解决方案1】:

    我已阅读Atomic Commit in SQLite 文档。如果您真的想了解正在发生的事情,这可能并不过分,但简而言之,交易是这样的:

    1. 锁定数据库文件
      • 创建回滚日志
        1. 确定数据库文件的哪些部分将发生变化
      • 将这些页面的副本写入日志文件
      • 写入日志文件头
      • 将您的预期更改写入数据库文件
      • 删除回滚日志(这是提交

    当用户完成与妈妈的交谈并重新启动您的应用程序时,当它尝试打开数据库文件时,如果存在回滚日志,它将使用类似的安全过程将原始数据写回数据文件.即使您丢失了交易并丢失了回滚,一旦妈妈的神经衰弱得到适当的阻止并且他可以一次运行应用程序超过几秒钟,它最终也会得到解决。

    如果是我,我会相信这些交易。有这么多 SQLite 用户,即使是在嵌入式应用程序中,我认为事务提交失败如果不能正常工作,将成为全网非常热门的话题。

    【讨论】:

      【解决方案2】:

      您是否在使用带有 SQLite 后端的 CoreData?如果是这样,我实际上发现处理此问题的最佳方法是创建两个单独的 NSManagedObjectContexts(一个只读和一个编辑)。该过程完成后,只需保存“编辑”上下文,然后两个上下文将同步。如果您在操作过程中发生了一些事情,编辑上下文将不会被保存,所以您会没事的。

      【讨论】:

      • 我没有使用 Core Data;第一个版本是在 Core Data 可用于 Cocoa Touch 之前发布的。我假设这相当于“将所有内容加载到内存中,然后将其写入新文件”?
      • 好吧,CoreData 让处理 SQLite 的许多问题完全消失了。虽然我以前从未这样做过,但网上有一些类展示了如何从 SQLite 导入到 SQLight 支持的 CoreData 存储中。如果时间允许,我强烈建议走这条路;它将为您省去很多麻烦。
      • Core Data 很棒,但我有非常明智的理由不使用它,但遗憾的是不适合这个评论框。不过,我确信迁移到它会使您的答案更适合我的问题。
      猜你喜欢
      • 2012-10-14
      • 2012-06-17
      • 1970-01-01
      • 1970-01-01
      • 2013-10-25
      • 2014-10-24
      • 2020-10-30
      • 2022-12-16
      相关资源
      最近更新 更多