我正在编写的 iPhone 应用程序中有一个 sqlite 数据库。我在后台线程中运行的以下代码出现错误。在后台线程中,我调用这个方法:
- (BOOL) songIsInDatabase:(NSString *)songTitle
{
NSString *docsDir;
NSArray *dirPaths;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
//Build the path to the database file
NSString *databasePath = [[NSString alloc] initWithString:[docsDir stringByAppendingPathComponent:@"Database.db"]];
const char *dbpath = [databasePath UTF8String];
sqlite3_stmt *statement;
if(sqlite3_open(dbpath, &DB) == SQLITE_OK){
NSString *insertSQL = [NSString stringWithFormat:@"select * from Bpm_Table where song_title = '%@'", songTitle];
const char *insert_stmt = [insertSQL UTF8String];
if(sqlite3_prepare_v2(DB, insert_stmt, -1, &statement, NULL) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
return YES;
break;
}
}else{
NSLog(@"the error is %s", sqlite3_errmsg(DB));
}
sqlite3_finalize(statement);
}
[databasePath release];
return NO;
}
然后我调用这个方法:
- (void) addSongToDatabase: (NSString *) songTitle andBPM: (int)bpm andGenre: (NSString *) genre
{
NSString *docsDir;
NSArray *dirPaths;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
//Build the path to the database file
NSString *databasePath = [[NSString alloc] initWithString:[docsDir stringByAppendingPathComponent:@"Database.db"]];
const char *dbpath = [databasePath UTF8String];
sqlite3_stmt *statement;
if(sqlite3_open(dbpath, &DB) == SQLITE_OK){
NSString *insertSQL = [NSString stringWithFormat:@"insert or replace into Bpm_Table (song_title, bpm, genre) values (\"%@\", \"%d\", \"%@\")", songTitle, bpm, genre];
const char *insert_stmt = [insertSQL UTF8String];
if(sqlite3_prepare(DB, insert_stmt, -1, &statement, NULL) == SQLITE_OK){
if(sqlite3_step(statement) == SQLITE_DONE)
{
} else {
NSLog(@"error: %s", sqlite3_errmsg(DB));
}
}sqlite3_finalize(statement);
}
[databasePath release];
}
如果我一个接一个地运行这两种方法,我会收到一条错误消息,指出“数据库已锁定”。我在谷歌搜索后添加了 sqlite3_finalize
语句,希望能解决这个问题。如果我注释掉其中任何一个方法,我就不会收到此错误。
有谁知道怎么了?
sqlite3_close(DB);
之后添加此行
sqlite3_finalize(statement);
更新 -
您在 while 循环之一中返回 YES -
while (sqlite3_step(statement) == SQLITE_ROW)
{
return YES;
break;
}
所以在这里你既没有完成也没有关闭数据库..如果每次打开它都需要关闭
SQLite 不提供任何类型的“锁等待”机制。
您的基本选项是:
从一个线程进行所有访问。
如果您想删除数据库已锁定错误,请按照以下步骤操作 1.将数据库文件复制到其他位置。 2.然后用复制的数据库替换数据库 3.这将取消引用所有正在访问您的数据库文件的进程
sqlite3_close(DB)
,可能是因为您的方法试图同时访问同一个数据库。 试试这行代码
sqlite3_busy_timeout(DB, 500);
在方法中的
sqlite3_open
和
sqlite3_prepare_v2
之间的某个地方,您会收到“数据库已锁定”错误。数据库连接将在放弃之前尝试在 500 毫秒内进行写入/读取,这通常足以逃脱锁定。
sqlite3_close(db)
将其关闭。
如果不关闭,那么访问数据库的进程将在后台运行,从而导致数据库被锁定错误。
因此,您需要在 Windows 任务管理器中结束所有 Python 进程,重新启动它们,应该没问题(
if这实际上是问题的原因)。
我正在使用SQLite3。
我希望这也对你有用!