使用 FMDB for iOS 锁定数据库
Posted
技术标签:
【中文标题】使用 FMDB for iOS 锁定数据库【英文标题】:Database locked using FMDB for iOS 【发布时间】:2014-04-08 15:48:28 【问题描述】:首先,我想说的是,我真的很难在后台线程中配置和使用我的 SQLite DB,以免主线程被阻塞。
在网上某处找到一个小指南后,我决定使用 FMDB 包装器。
与数据库操作相关的所有方法都在同一个类中,这就是我遇到错误的地方:
我已经这样设置了静态变量:
static FMDatabaseQueue *_queue;
static NSOperationQueue *_writeQueue;
static NSRecursiveLock *_writeQueueLock;
然后在我的 init 方法中我有:
- (id)init
self = [super init];
if (self)
_queue = [FMDatabaseQueue databaseQueueWithPath:[self GetDocumentPath]];
_writeQueue = [NSOperationQueue new];
[_writeQueue setMaxConcurrentOperationCount:1];
_writeQueueLock = [NSRecursiveLock new];
return self;
这是给我错误的方法:
- (void)UpdateTime:(NSString *)idT :(int)userId
[_writeQueue addOperationWithBlock:^
[_writeQueueLock lock];
[_queue inDatabase:^(FMDatabase *dbase)
AppDelegate *deleg = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if (![dbase executeUpdate:@"update orari set orario=datetime(orario, '? minutes') where nome=? and dataid>=? and idutente=?"
withArgumentsInArray:@[[NSNumber numberWithFloat:deleg.diff], deleg.nome, [NSNumber numberWithInt:deleg.idMed], [NSNumber numberWithInt: userId]]])
NSLog(@"error");
];
[_writeQueueLock unlock];
];
[_writeQueue addOperationWithBlock:^
[_writeQueueLock lock];
[_queue inDatabase:^(FMDatabase *dbase)
AppDelegate *deleg = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if (![dbase executeUpdate:@"UPDATE orari SET presa=1 where dataid=? and idutente=?"
withArgumentsInArray:@[[NSNumber numberWithInt:deleg.identific], [NSNumber numberWithInt: userId]]])
NSLog(@"error");
];
[_writeQueueLock unlock];
];
[self AddNotification];
这些是我得到的错误:
*** -[NSRecursiveLock dealloc]: lock (<NSRecursiveLock: 0xc38b350> '(null)') deallocated while still in use
DB Error: 5 "database is locked"
*** -[NSRecursiveLock unlock]: lock (<NSRecursiveLock: 0x13378d20> '(null)') unlocked when not locked
根据我阅读的指南,我认为对我的数据库的访问会被“序列化”,并且每次更新都会被添加到队列中并一次执行一个。
如您所见,我有很多关于这个主题的知识,所以任何帮助都将不胜感激。
【问题讨论】:
嗨 Aleph72,你有没有找到解决这个问题的方法?我遇到了类似的问题,并且还认为数据库进程已序列化。现在我收到 DB 错误:5“数据库已锁定。” 【参考方案1】:据我所知,您尚未创建此初始化调用的共享实例或单例实例
- (id)init
self = [super init];
if (self)
_queue = [FMDatabaseQueue databaseQueueWithPath:[self GetDocumentPath]];
_writeQueue = [NSOperationQueue new];
[_writeQueue setMaxConcurrentOperationCount:1];
_writeQueueLock = [NSRecursiveLock new];
return self;
这应该是一个单例调用,因为您将创建多个 NSOperationQueue 实例,这将使数据库在多线程环境中易受攻击,尝试使用 GCD 或
对您的数据库进行单例调用static DBManager *sharedInstance = nil;
+(DBManager*)getSharedInstance
if (!sharedInstance)
sharedInstance = [[super allocWithZone:NULL]init];
_queue = [FMDatabaseQueue databaseQueueWithPath:[self GetDocumentPath]];
_writeQueue = [NSOperationQueue new];
[_writeQueue setMaxConcurrentOperationCount:1];
_writeQueueLock = [NSRecursiveLock new];
return sharedInstance;
它可能会解决您的问题,这是我第一次在这里回答,我是环境新手,所以请有点宽容:) 谢谢
【讨论】:
以上是关于使用 FMDB for iOS 锁定数据库的主要内容,如果未能解决你的问题,请参考以下文章