2016-03-04 110 views
0

我有多重列表,我希望以多线程方式存储在我的sqlite数据库使用activeAndroid。我为每个列表运行一个线程以保持。ActiveAndroid.beginTransaction()和多线程

每个线程的主体看起来像这样。

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

由于每个线程一个接一个地运行,事务似乎向数据库添加了一个锁。

没有使用交易事情按预期工作,但任务相当缓慢(a hundred time slowest)。

这个问题讨论here

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

回答

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()文件锁定被破坏。如果多个进程可能试图同时访问文件,则应避免将NFS数据库文件放在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

+0

好知道。感谢您突出显示此问题 – aiqency