2

我在 Android 中使用 sqlite 事务:

SQLiteDatabase database = sqlite_helper.getWritableDatabase();

database.beginTransaction();
...
database.setTransactionSuccessful();
database.endTransaction();

我的问题是:
1. 我应该endTransaction()像这样放在 finally 代码块中:</p>

try {
    database.beginTransaction();
    ...
    database.setTransactionSuccessful();
}
finally {
    database.endTransaction();
}

如果在数据库操作过程中出现异常,数据库是否会自动回滚而不使用“finally”?

  1. 当事务没有结束时,其他线程可以读写同一个数据库吗?我听说 Android 中的 sqlite 是线程安全的,但我不确定。我想在交易过程中会有一些问题。如果另一个线程使用相同的连接写入相同的数据库,是否会引发错误?
    我曾经在我的应用程序中发现这个错误,但我不知道它是否与线程安全问题有关:

android.database.sqlite.SQLiteMisuseException: library routine called out of sequence:

, 编译时

有人帮我回答这些问题吗?非常感谢!

4

3 回答 3

5

1.您应该始终将 endTransaction 放在 finally 块中

2.SQLite 中的事务是线程安全的,参见文档http://www.sqlite.org/atomiccommit.html

于 2012-10-25T07:05:17.620 回答
1

您应该始终放入endTransaction()一个finally块中(另请参阅文档)。否则,数据库将无法注意到发生了异常。

结束事务的唯一其他方法是关闭连接,在这种情况下 SQLite 会自动回滚任何活动事务。

只要一个连接写入数据库(这意味着事务处于活动状态),就没有其他连接可以读取或写入。因此,您应该注意不要忘记结束交易。

你永远不应该从多个线程中写入;如果一个线程结束事务而另一个线程仍在写入会发生什么?

SQLiteMisuseException可能相关,也可能不相关;如果没有看到代码,这是不可能说的。

于 2012-10-25T07:05:50.943 回答
0

是的,您应该使用 finally 块。这是我使用的一个简单的线程安全方法:

/**
 * Call for multiple DB insertion transactions.  It is thread safe and fast!
 */
private synchronized void writeTransaction(Runnable task) {
    try {
        db.beginTransaction();
        task.run();
        db.setTransactionSuccessful();
    } finally {
        db.endTransaction();
    }
}

synchronized关键字用它的包含对象锁定方法,从而使其线程安全......

于 2019-02-27T03:42:52.120 回答