ActiveAndroid.beginTransaction()和多线程

时间:2016-03-04 13:02:33

标签: android multithreading sqlite activeandroid

我有多个列表,我希望使用activeAndroid以多线程方式存储在我的sqlite数据库中。我为每个列表运行一个线程来保持。

每个线程的主体都是这样的。

ActiveAndroid.beginTransaction();
try {
   for (MyObjToPersist e : myListOfObjToPersist){
        e.save();
   }
   ActiveAndroid.setTransactionSuccessful();
}
finally {
   ActiveAndroid.endTransaction();
}

该事务似乎为数据库添加了一个锁,因为每个线程都是一个接一个地运行。

不使用事务处理按预期工作,但任务很慢(a hundred time slowest)。

本主题正在讨论here

有人知道如何避免这种行为吗? 感谢

1 个答案:

答案 0 :(得分:0)

TL; DR :只有一个线程可以修改,但所有线程都可以读取数据。

  

Can multiple applications or multiple instances of the same application access a single database file at the same time?

     

多个进程可以同时打开同一个数据库。多个进程可以同时执行SELECT。但是,只有一个进程可以随时对数据库进行更改。

     

SQLite使用读取器/写入器锁来控制对数据库的访问。 (在Win95 / 98 / ME下,缺少对读取器/写入器锁的支持,而是使用概率模拟。)但请注意:如果数据库文件保存在NFS文件系统上,则此锁定机制可能无法正常工作。这是因为许多NFS实现都会破坏fcntl()文件锁定。如果多个进程可能同时尝试访问该文件,则应避免将SQLite数据库文件放在NFS上。在Windows上,Microsoft的文档说如果您没有运行Share.exe守护程序,则在FAT文件系统下锁定可能不起作用。对Windows有很多经验的人告诉我,网络文件的文件锁定是非常错误的,并且不可靠。如果他们说的是真的,在两台或多台Windows机器之间共享SQLite数据库可能会导致意外问题。

     

我们知道没有其他嵌入式SQL数据库引擎支持与SQLite一样多的并发性。 SQLite允许多个进程一次打开数据库文件,并允许多个进程一次读取数据库。当任何进程想要写入时,它必须在更新期间锁定整个数据库文件。但这通常只需要几毫秒。其他流程只是等待作者完成然后继续他们的业务。其他嵌入式SQL数据库引擎通常只允许单个进程一次连接到数据库。

     

但是,客户端/服务器数据库引擎(如PostgreSQL,MySQL或Oracle)通常支持更高级别的并发性,并允许多个进程同时写入同一数据库。这在客户端/服务器数据库中是可能的,因为总有一个良好控制的服务器进程可用于协调访问。如果您的应用程序需要大量并发,那么您应该考虑使用客户端/服务器数据库。   但经验表明,大多数应用程序需要更少   并发性超出了设计师的想象。   当SQLite尝试访问由另一个进程锁定的文件时,默认行为是返回SQLITE_BUSY。您可以使用sqlite3_busy_handler()或sqlite3_busy_timeout()API函数从C代码调整此行为。

https://www.sqlite.org/faq.html#q5