简体   繁体   English

在Objective-C中同步sqlite数据库

[英]Synchronize sqlite database in objective-C

I have a view in which I am inserting data in a background thread to sqlite database coming from server. 我有一个视图,我正在将后台线程中的数据插入到来自服务器的sqlite数据库中。 Now when user taps and navigate to another view in which I have to read the contents from this database, but I am not able to fetch the contents as the database is already open in background thread of last view and it gives error "database is locked". 现在,当用户点击并导航到另一个视图时,我必须从该数据库中读取内容,但是由于该数据库已经在上一个视图的后台线程中打开,因此我无法提取内容,并且出现错误“数据库已锁定”。

NOTE: both the operations are in different Tables ie I am writing in different table and reading from other table. 注意:两种操作都在不同的表中,即我正在不同的表中写入并从其他表中读取。

Does sqlite support multi threading, If yes then how can I remove the lock from database? sqlite是否支持多线程?如果是,那么如何从数据库中删除锁?

SQLite does support multi-threading, but it does not support simultaneous access to the database from multiple threads. SQLite确实支持多线程,但是不支持从多个线程同时访问数据库。

If you are accessing SQLite from multiple threads in Objective-C you should use some kind of locking mechanism to coordinate access to the database handle. 如果要从Objective-C中的多个线程访问SQLite,则应使用某种锁定机制来协调对数据库句柄的访问。 One option is the @synchronized keyword. 一种选择是@synchronized关键字。

As for reading from the database at the same time that inserts are happening on a different thread, you'll need to get creative. 至于在不同线程上进行插入操作的同时从数据库中读取数据,则需要发挥创造力。

One option is to put the two tables into two different databases and create two different connections to them. 一种选择是将两个表放入两个不同的数据库,并为其创建两个不同的连接。

Further reading on the nature of using SQLite in a multi-threaded environment: 进一步阅读在多线程环境中使用SQLite的本质:

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

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

SQLite supports multithreading. SQLite支持多线程。 You can share your connection handle/object between threads, they'll sync their access nicely. 您可以在线程之间共享连接句柄/对象,它们将很好地同步访问。

EDIT: pass the sqlite3 object (the one that sqlite3_open() returns as the second parameter) to the thread instead of reopening the database in the thread. 编辑:将sqlite3对象( sqlite3_open()作为第二个参数返回的对象)传递给线程,而不是在线程中重新打开数据库。 Something like this: 像这样:

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

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

Inside the thread, recover the SQLite3 object like this: 在线程内部,像这样恢复SQLite3对象:

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

Sqlite supports multi-threading in the sense of "writing so fast to avoid concurrency problems". Sqlite以“编写得如此之快以避免并发问题”的意义上支持多线程。 The reality is that there shouldn't be lock troubles in case of read only queries but if you want to write too... you could meet the SQLITE_BUSY error. 现实情况是,在只读查询的情况下不应存在锁定麻烦,但是如果您也想写...,您可能会遇到SQLITE_BUSY错误。 You can avoid it in several ways: 您可以通过几种方式避免它:

  • either doing all queries into the same thread (but if you could do it...no questions on stackoverflow :-) ) 要么在同一个线程中执行所有查询(但是如果可以的话...关于stackoverflow的问题:-))

  • or, as mentioned above, split database tables into two or more files (grouping together tables with less concurrency accesses or with read only accesses) and creating for each file a different db connection 或者,如上所述,将数据库表拆分为两个或多个文件(将并发访问较少或只读访问的表分组在一起),并为每个文件创建不同的数据库连接

  • or, as mentioned above, using a thread synchronizing approach on each method (or block of code) that does the query (to be sure that db will be locked when you start the transaction use "BEGIN IMMEDIATE TRANSACTION") 或者,如上所述,对执行查询的每个方法(或代码块)使用线程同步方法(以确保在启动事务时使用“ BEGIN IMMEDIATE TRANSACTION”锁定数据库)

  • or, handle the sqlite:busy error with the 2 callbacks provided by the c api, "sqlite_busy_handler" and "sqlite_busy_timeout" 或者,使用c api提供的2个回调“ sqlite_busy_handler”和“ sqlite_busy_timeout”来处理sqlite:busy错误

  • or, after receiving lock errors waiting for 1-2 seconds and retry (better approach the point above i think) 或者,在收到等待1-2秒的锁定错误并重试之后(更好地接近我认为的上述观点)

I prefer to reduce concurrency splitting db and then if needed synchronizing threads accesses to query code. 我更喜欢减少并发拆分数据库,然后在需要时将线程访问同步到查询代码。 It's just your choice... 这只是您的选择...

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

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