我正在尝试确定在iOS上访问sqlite数据库是否是线程安全的。我正在编写一个非App Store应用程序(或可能是启动守护程序),因此苹果的批准不是问题。所涉及的数据库是内置的 sms.db ,因此可以确定操作系统也会访问该数据库进行读取和写入。我只想能够安全地读取它。
我已经阅读了关于使用sqlite从多个进程中读取的内容:
多个进程可以同时打开同一个数据库。 多个进程可以同时执行SELECT语句。但是,在任何时刻只有一个进程可以对数据库进行更改。
我知道SQLite可以编译出线程安全功能,并且可以使用sqlite3_threadsafe()
进行测试。在iOS 5.0.1上运行此代码:
int safe = sqlite3_threadsafe();
结果如下:
执行结果为2。 根据这个,这意味着互斥锁定是可用的。但是,这并不一定意味着它正在使用中。
我不太清楚线程安全性是在每个连接、每个数据库还是全局基础上动态启用的。
我也读了这个。看起来sqlite3_config()
可以用于启用安全的多线程,但当然,我没有控制,也没有可见性来了解操作系统本身可能如何使用此调用(对吗?)。如果我在我的应用程序中再次进行该调用,那么它是否会使读取数据库变得安全,还是仅为使用相同的sqlite3
数据库句柄的多个线程在我的应用程序中消除冲突访问?
无论如何,我的问题是...
我能够安全地读取由iOS访问的这个数据库吗?如果可以,怎样才能做到安全?
BEGIN EXCLUSIVE TRANSACTION;
语句? - NateBEGIN EXCLUSIVE TRANSACTION
用于在事务开始时获取排他锁。默认情况下,SQLite 尽可能长地等待。根据文档:请注意,BEGIN 命令不会在数据库上获取任何锁。在 BEGIN 命令之后,第一次执行 SELECT 语句将获取共享锁。在第一次执行 INSERT、UPDATE 或 DELETE 语句时将获取保留锁。... - Jordan Minersqlite3_exec()
,它将作为隐式事务运行。但是,这个答案可能只是建议使用BEGIN IMMEDIATE
而不是仅仅使用BEGIN
。这会使您的代码更清晰,但您并不一定要这样做。... - Jordan Miner