Исключение SQLite: SQLite Занят

может ли кто - нибудь предоставить какие-либо данные об этой ошибке. Я пытаюсь вставить в таблицу с помощью Objective C.

пока я это делаю, я получаю сообщение об ошибке SQLite занят. Почему это происходит?

5 ответов


Если я правильно понял, "занят" означает, что вы не можете получить блокировку. Кажется, что какой-то другой процесс (или поток и т. д.) имеет блокировку на базу.

Блокировка Файлов И Параллелизм В SQLite Версии 3


Если вы получаете в результате при вызове функции sqlite3 код ошибки SQLITE_BUSY, это означает, как заметил drdaeman, что БД была заблокирована тем же процессом или одним потоком в вашем процессе.

правильный способ справиться с этой ситуацией-попробовать операцию в цикле, и если код возврата по-прежнему SQLITE_BUSY, подождать некоторое время (вы решаете значение тайм-аута), а затем повторить операцию в следующей итерации цикла.

например, следующий фрагмент кода взят из Objective C wrapper FMDB (http://code.google.com/p/flycode/source/browse/trunk/fmdb) показывает, как подготовить инструкцию для запроса с учетом того, что некоторые операции могут возвращать SQLITE_BUSY:

int numberOfRetries = 0;
BOOL retry          = NO;

if (!pStmt) {
    do {
        retry   = NO;
        rc      = sqlite3_prepare(db, [sql UTF8String], -1, &pStmt, 0);

        if (SQLITE_BUSY == rc) {
            retry = YES;
            usleep(20);

            if (busyRetryTimeout && (numberOfRetries++ > busyRetryTimeout)) {
                NSLog(@"%s:%d Database busy (%@)", __FUNCTION__, __LINE__, [self databasePath]);
                NSLog(@"Database busy");
                sqlite3_finalize(pStmt);
                [self setInUse:NO];
                return nil;
            }
        }
        else if (SQLITE_OK != rc) {


            if (logsErrors) {
                NSLog(@"DB Error: %d \"%@\"", [self lastErrorCode], [self lastErrorMessage]);
                NSLog(@"DB Query: %@", sql);
                if (crashOnErrors) {

                    NSAssert2(false, @"DB Error: %d \"%@\"", [self lastErrorCode], [self lastErrorMessage]);
                }
            }

            sqlite3_finalize(pStmt);

            [self setInUse:NO];
            return nil;
        }
    }
    while (retry);
}

кстати, если вам нужно получить доступ к sqlite, FMDB очень удобен и намного проще в использовании в отношении прямого доступа через собственные API C.


У меня была аналогичная проблема с SQLITE_BUSY при последовательной вставке в команды. Первая строка вставлена нормально, но когда приложение попыталось вставить вторую строку, я получил статус SQLITE_BUSY. После Google я узнал, что вы должны вызвать sqlite3_finalize() для операторов после их выполнения:http://www.sqlite.org/c3ref/finalize.html. Завершение моих утверждений решило мою проблему.


в моем случае, я забыл закрыть базу после ее использования. После фиксированной шахты:

sqlite3_finalize(statement);
sqlite3_close(contactDB);

FMDB по может также облегчить эти головные боли от вас легко.


Это было так же просто, как запустить командную строку как администратор для меня. В качестве альтернативы в UNIX вы можете использовать sudo при запуске базы данных.