捕获数据库错误的有效方法

时间:2012-06-26 20:38:24

标签: python database sqlite error-handling

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

  1. SQL逻辑错误或缺少数据库(偶尔会发生不可预测的事情)
  2. 数据库已锁定(如果正在由其他程序编辑,如SQLite数据库浏览器)
  3. 磁盘I / O错误(也会发生无法预料)
  4. 虽然这些错误并不经常发生,但是当他们这样做时,他们完全锁定了我的应用程序,所以我不能让他们站起来。

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

    问题是:仅仅提供此数据库访问功能及其公告不够,因为在65个模块中的所有数据库访问点在访问之后有代码假定数据库将成功返回数据或完成写入 - 如果没有,则代码必须具有该条件。但是编写这些条件需要仔细进入每个接入点,看看如何最好地处理它。对于我需要以这种方式进行修补的数百次数据库访问,这是非常费力和困难的。

    我愿意这样做,但我想我会询问是否有更有效/更聪明的方法,或者至少是一种有助于有效完成此修复的启发式方法。 < / p>

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

1 个答案:

答案 0 :(得分:1)

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

对于应用程序应如何对依赖于

等因素的错误做出反应,您仍有很多重要的选择
  • 是否有人参加,有时完全无人看管?
  • 延迟是否正常,或者及时报告数据库错误很重要?
  • 您描述的三种类型故障的相对频率是多少?

既然您有一个包装器,您可以使用它来执行一些常见的配置和错误处理,尤其是:

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

...但是有一个时刻你需要咬紧牙关并将错误输出到应用程序中,并查看所有特定呼叫者可能使用它做什么。