在Android中使用sqlite事务时的多线程问题

在Android中使用sqlite事务时的多线程问题,android,sqlite,android-sqlite,Android,Sqlite,Android Sqlite,我在Android中使用sqlite事务: SQLiteDatabase database = sqlite_helper.getWritableDatabase(); database.beginTransaction(); ... database.setTransactionSuccessful(); database.endTransaction(); 我的问题是: 1.我是否应该像这样将endTransaction()放在finally代码块中: try { databas

我在Android中使用sqlite事务:

SQLiteDatabase database = sqlite_helper.getWritableDatabase();

database.beginTransaction();
...
database.setTransactionSuccessful();
database.endTransaction();
我的问题是:
1.我是否应该像这样将
endTransaction()
放在finally代码块中:

try {
    database.beginTransaction();
    ...
    database.setTransactionSuccessful();
}
finally {
    database.endTransaction();
}
如果在数据库操作期间有exepctions,数据库是否会自动回滚而不使用“finally”?

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

    ,在编译时


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

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


    2.SQLite中的事务是线程安全的,请参见文档

    您应该始终将
    endTransaction()
    放入
    finally
    块(另请参见)。 否则,数据库将无法注意到异常的发生

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

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

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


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

    是的,您应该使用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关键字将方法与其包含的对象锁定,从而使其线程安全…

    链接没有提到“线程”一词。它是如何线程安全的?问题是,当来自另一个线程的事务打开时,另一个线程是否会创建新事务或运行新查询。那么它是线程安全的吗?根据我目前的经验,我会遇到奇怪的“连接池”错误。事务不是线程安全的。线程之间只共享一个
    SQLiteDatabase
    实例,因此数据库只能处于一个事务状态,这将由两个线程同时操作。如果一个线程开始一个事务,然后另一个线程尝试开始另一个事务,则会引发非法状态异常。Android beginTransaction和endTransaction是使用Java同步的实际begin和COMMIT命令的线程安全包装函数,即使它在内部使用单个数据库连接。如果您直接使用本机SQLite API(在Android中不太可能),那么它不是线程安全的。