2

我有一个桌面应用程序,它有 65 个模块,其中大约一半从 SQLite 数据库读取或写入。我发现数据库可以通过 3 种方式抛出 SQliteDatabaseError:

  1. SQL 逻辑错误或缺少数据库(不时发生不可预知的情况)
  2. 数据库被锁定(如果它正在被另一个程序编辑,如 SQLite 数据库浏览器)
  3. 磁盘 I/O 错误(也发生意外)

尽管这些错误并不经常发生,但当它们发生时,它们会完全锁定我的应用程序,因此我不能让它们一直存在。

因此,我开始重新编写数据库的每一次访问,使其成为指向其自己模块中通用“数据库访问函数”的指针。然后,该函数可以将这三个错误作为异常捕获,从而不会崩溃,并相应地提醒用户。例如,如果是“数据库被锁定错误”,它将宣布这一点并要求用户关闭任何也在使用数据库的程序,然后重试。(如果是其他错误,也许它会告诉用户稍后再试……还不确定)。更新所有数据库访问以执行此操作主要是将重定向复制/粘贴到通用功能 - 轻松工作。

问题是:仅仅提供这个数据库访问函数和它的声明是不够的,因为在 65 个模块中的所有数据库访问点都有代码跟随访问假设数据库将成功返回数据或完成一个写——当它没有写的时候,那个代码必须有一个条件。但是编写这些条件需要仔细研究每个访问点并了解如何最好地处理它。对于我需要以这种方式修补的数百个数据库访问来说,这既费力又困难。

我愿意这样做,但我想我会询问是否有更有效/更聪明的方法或至少启发式方法可以帮助有效地完成此修复。

(我应该声明这个应用程序没有特定的“架构”......它主要是可以称为“馄饨代码”的东西,其中 GUI 和数据库调用和逻辑都在“一起”的单元中。我是目前不愿意在 MVC 或类似的东西中重写整个项目的架构,尽管我会考虑在未来的项目中使用它。)

4

1 回答 1

1

你的直觉是对的。如果不单独检查每个数据库访问点,就无法为应用程序增加健壮性。

对于应用程序如何对取决于以下因素的错误做出反应,您仍然有很多重要的选择,

  • 它是有人看管的,还是有时完全无人看管的?
  • 延迟可以吗,还是及时报告数据库错误很重要?
  • 您描述的三种故障的相对频率是多少?

现在你有了一个包装器,你可以用它来做一些常见的配置和错误处理,尤其是:

  • 设置合理的连接超时
  • 设置合理的繁忙超时
  • 在客户端强制执行命令超时
  • 自动重试错误,尤其是SQLITE_BUSY(在重试之间插入较大的延迟,重试几次后失败)
  • 使用异常来减少应用程序级处理程序的数量。您可能能够在数据库错误时重新启动整个应用程序。但是,只有在您确信自己在哪个状态中止应用程序时才这样做;事务的一致使用可以确保重新启动方法不会留下不一致的数据。
  • 当您检测到锁定错误时向人寻求帮助

...but there comes a moment where you need to bite the bullet and let the error out into the application, and see what all the particular callers are likely to do with it.

于 2012-06-26T21:04:59.273 回答