繁体   English   中英

在Objective-C中同步sqlite数据库

[英]Synchronize sqlite database in objective-C

我有一个视图,我正在将后台线程中的数据插入到来自服务器的sqlite数据库中。 现在,当用户点击并导航到另一个视图时,我必须从该数据库中读取内容,但是由于该数据库已经在上一个视图的后台线程中打开,因此我无法提取内容,并且出现错误“数据库已锁定”。

注意:两种操作都在不同的表中,即我正在不同的表中写入并从其他表中读取。

sqlite是否支持多线程?如果是,那么如何从数据库中删除锁?

SQLite确实支持多线程,但是不支持从多个线程同时访问数据库。

如果要从Objective-C中的多个线程访问SQLite,则应使用某种锁定机制来协调对数据库句柄的访问。 一种选择是@synchronized关键字。

至于在不同线程上进行插入操作的同时从数据库中读取数据,则需要发挥创造力。

一种选择是将两个表放入两个不同的数据库,并为其创建两个不同的连接。

进一步阅读在多线程环境中使用SQLite的本质:

http://www.sqlite.org/threadsafe.html

http://www.sqlite.org/faq.html#q6

SQLite支持多线程。 您可以在线程之间共享连接句柄/对象,它们将很好地同步访问。

编辑:将sqlite3对象( sqlite3_open()作为第二个参数返回的对象)传递给线程,而不是在线程中重新打开数据库。 像这样:

sqlite3 *MyDatabase; //Initialized somewhere
NSArray *DataForThread = [NSArray arrayWithObjects:
    request,
    [NSValue valueWithPointer: MyDatabase],
    nil];

[self performSelectorInBackground:@selector(processResponseInBackground:)        withObject:DataForThread];

在线程内部,像这样恢复SQLite3对象:

sqlite3 *MyDatabase = [[ThreadData objectAtIndex:1] pointerValue];

Sqlite以“编写得如此之快以避免并发问题”的意义上支持多线程。 现实情况是,在只读查询的情况下不应存在锁定麻烦,但是如果您也想写...,您可能会遇到SQLITE_BUSY错误。 您可以通过几种方式避免它:

  • 要么在同一个线程中执行所有查询(但是如果可以的话...关于stackoverflow的问题:-))

  • 或者,如上所述,将数据库表拆分为两个或多个文件(将并发访问较少或只读访问的表分组在一起),并为每个文件创建不同的数据库连接

  • 或者,如上所述,对执行查询的每个方法(或代码块)使用线程同步方法(以确保在启动事务时使用“ BEGIN IMMEDIATE TRANSACTION”锁定数据库)

  • 或者,使用c api提供的2个回调“ sqlite_busy_handler”和“ sqlite_busy_timeout”来处理sqlite:busy错误

  • 或者,在收到等待1-2秒的锁定错误并重试之后(更好地接近我认为的上述观点)

我更喜欢减少并发拆分数据库,然后在需要时将线程访问同步到查询代码。 这只是您的选择...

暂无
暂无

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

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