繁体   English   中英

ActiveAndroid.beginTransaction()和多线程

[英]ActiveAndroid.beginTransaction() and multithread

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

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

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

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

如果不使用事务,事情将按预期工作,但是任务相当缓慢( 最慢一百倍 )。

这个主题在这里讨论。

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

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文件系统上,则该锁定机制可能无法正常工作。 这是因为fcntl()文件锁定在许多NFS实现中都被破坏了。 如果多个进程可能试图同时访问文件,则应避免将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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM