【问题标题】:Android: can exceptions be thrown from SQLite database during transactions?Android:事务期间可以从 SQLite 数据库中抛出异常吗?
【发布时间】:2017-02-05 19:28:37
【问题描述】:

假设我有两个线程需要在 SQLite 数据库(在 Android 中)上执行原子的 Read-Mofify-Write 操作。

为了保证原子性,我用数据库事务包装了逻辑:

try {
    database.beginTransaction();
    ... read-modify-write logic here
    database.setTransactionSuccessful();
}
finally {
    database.endTransaction();
}

默认情况下,此事务是 EXCLUSIVE 的(至少在 Android 上是这样)。性能(吞吐量)不是一个因素(客户端 - 预期的交易不多)。

到目前为止一切都很好,但有一个问题困扰着我:虽然上面的try-finally 模式将确保在抛出异常的情况下数据库的一致性,但如果真的发生了异常并且我没有捕捉到它 - 我的应用程序会崩溃...

当涉及到我自己的代码时,我知道可以抛出哪些异常以及如何处理它们,但是我试图了解在这种情况下 SQLite 数据库本身可以抛出哪些异常(如果有的话),但我不能在任何地方都可以找到它。

所以,我对上述代码的问题是:

  1. 单线程执行此代码时会抛出哪些致命异常(致命 = 无法恢复;让应用程序崩溃)?
  2. 单线程执行这段代码会抛出哪些非致命异常,如何处理?
  3. 如果一个线程已经在事务中,而另一个线程尝试启动一个新事务,那么第二个线程会阻塞直到第一个线程完成,还是会抛出异常?

提前致谢

【问题讨论】:

    标签: android sqlite android-sqlite


    【解决方案1】:

    在数据库操作期间,可能会发生各种违反约束的情况,但这些通常表明存在编程错误。 此外,读取或写入数据库文件可能会遇到任何随机硬件错误,从而导致任何随机异常。

    最后,如果数据库被锁定的时间过长,你会得到一个“数据库被锁定”的异常。可以用PRAGMA busy_timeout调整特定连接的等待时间(默认值没用)。

    【讨论】:

    • 哦,天哪,我自己应该考虑一下违反约束的问题...您也可以帮我澄清一下“严重性”吗? 1)我决定违反约束是致命的还是可恢复的,对吗? 2)您提到的硬件错误可能被认为是罕见的致命错误并被忽略(即应用程序崩溃),对吗? 3)如果我理解正确,如果等待线程等待的时间过长,会抛出“数据库锁定”异常,对吧?我会说这表明实现错误并且可以被视为致命的(我的应用程序不是关键系统)?谢谢
    • 您无法处理您不知道的错误。 “太长”取决于。
    • 明白。谢谢
    猜你喜欢
    • 1970-01-01
    • 2012-07-17
    • 1970-01-01
    • 1970-01-01
    • 2012-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多