[英]Synchronize sqlite database in objective-C
我有一个视图,我正在将后台线程中的数据插入到来自服务器的sqlite数据库中。 现在,当用户点击并导航到另一个视图时,我必须从该数据库中读取内容,但是由于该数据库已经在上一个视图的后台线程中打开,因此我无法提取内容,并且出现错误“数据库已锁定”。
注意:两种操作都在不同的表中,即我正在不同的表中写入并从其他表中读取。
sqlite是否支持多线程?如果是,那么如何从数据库中删除锁?
SQLite确实支持多线程,但是不支持从多个线程同时访问数据库。
如果要从Objective-C中的多个线程访问SQLite,则应使用某种锁定机制来协调对数据库句柄的访问。 一种选择是@synchronized关键字。
至于在不同线程上进行插入操作的同时从数据库中读取数据,则需要发挥创造力。
一种选择是将两个表放入两个不同的数据库,并为其创建两个不同的连接。
进一步阅读在多线程环境中使用SQLite的本质:
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.