sqlite错误数据库被锁定

问题描述 投票:0回答:8

我正在编写的 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 语句,希望能解决这个问题。如果我注释掉其中任何一个方法,我就不会收到此错误。


有谁知道怎么了?

iphone database sqlite
8个回答
12
投票
sqlite3_close(DB);

 之后添加此行 
sqlite3_finalize(statement);

更新 -

您在 while 循环之一中返回 YES -

while (sqlite3_step(statement) == SQLITE_ROW) { return YES; break; }

所以在这里你既没有完成也没有关闭数据库..如果每次打开它都需要关闭


6
投票

SQLite 不提供任何类型的“锁等待”机制。

您的基本选项是:

从一个线程进行所有访问。
  1. 对所有访问使用单独的锁定协议。
  2. 如果出现“数据库已锁定”错误,请稍等片刻,然后重试。

5
投票

如果您想删除数据库已锁定错误,请按照以下步骤操作 1.将数据库文件复制到其他位置。 2.然后用复制的数据库替换数据库 3.这将取消引用所有正在访问您的数据库文件的进程


5
投票
sqlite3_close(DB)

,可能是因为您的方法试图同时访问同一个数据库。 试试这行代码

sqlite3_busy_timeout(DB, 500);

在方法中的
sqlite3_open

sqlite3_prepare_v2
之间的某个地方,您会收到“数据库已锁定”错误。
数据库连接将在放弃之前尝试在 500 毫秒内进行写入/读取,这通常足以逃脱锁定。


3
投票
sqlite3_close(db)

将其关闭。


如果不关闭,那么访问数据库的进程将在后台运行,从而导致数据库被锁定错误。


0
投票


0
投票

因此,您需要在 Windows 任务管理器中结束所有 Python 进程,重新启动它们,应该没问题(

if

这实际上是问题的原因)。


-3
投票

我正在使用SQLite3。

我希望这也对你有用!

© www.soinside.com 2019 - 2024. All rights reserved.