xcode sqlite3 - iOS - 数据库被锁定

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12929104/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 01:50:40  来源:igfitidea点击:

sqlite3 - iOS - database is locked

iosxcodesqlite

提问by javiazo

I am developing an app for ipad and i am using sqlite sentences (select, update, insert, delete).

我正在为 ipad 开发一个应用程序,我正在使用 sqlite 语句(选择、更新、插入、删除)。

I open (sqlite3_open) the database at the beginning and close (sqlite3_close) at the end of each sentence. But sometimes i′ve got the "database is locked" message.

我在每个句子的开头打开(sqlite3_open)数据库并在每个句子的结尾关闭(sqlite3_close)。但有时我会收到“数据库被锁定”的消息。

I don′t know what can i do to solve this.

我不知道我能做些什么来解决这个问题。

Thanks and sorry for this little information.

感谢并抱歉提供这些小信息。

回答by George

If I'm not mistaken , the problem with sqllite is that you can only access it once at a time. If you have multiple threads, you can run in this situation. Example:

如果我没记错的话,sqllite 的问题是你一次只能访问它一次。如果你有多个线程,你可以在这种情况下运行。例子:

Run method1 (which accesses the database) on thread t1. Run method2 (which accesses the database) on thread t2 after x seconds.

在线程 t1 上运行 method1(访问数据库)。x 秒后在线程 t2 上运行 method2(访问数据库)。

If method1 is not finished in those x seconds , both methods will access it at the same time. And , as I said , I know that sqllite does not support this.

如果 method1 在这 x 秒内未完成,则两种方法将同时访问它。而且,正如我所说,我知道 sqllite 不支持这一点。

You should try to flag the usage of your database and if you want to access it but it is in use , try again after x seconds. Like this:

您应该尝试标记数据库的使用情况,如果您想访问它但它正在使用中,请在 x 秒后重试。像这样:

- (void) generalMethodThatUsesDatabses
{
    if(databaseIsUsed)
    {
         [self performSelector:@selector(generalMethodThatUsesDatabses) withObject:nil afterDelay:5];
          return;
    }

    databaseIsUsed = TRUE;   //global bool variable


    //your code here

    databaseIsUsed = FALSE;

}

Hope this helps. Cheers!

希望这可以帮助。干杯!

回答by Vincent

You probably opened the database before using the same simulator. To conclude all actions to a database and release all resources you always have to use both (!) statements:

您可能在使用同一个模拟器之前打开了数据库。要结束对数据库的所有操作并释放所有资源,您始终必须使用两个 (!) 语句:

sqlite3_finalize(statement);
sqlite3_close(database);

回答by Serguei Fedorov

A good way to solve this is to wrap this into a C++ library. This way, you can can create the library wrapper on the stack. This means that the moment that the function goes out of scope, you can close the connection in the destructor.

解决此问题的一个好方法是将其包装到 C++ 库中。这样,您可以在堆栈上创建库包装器。这意味着在函数超出范围的那一刻,您可以在析构函数中关闭连接。

(note that I use reference counting for the Objective-C)

(请注意,我对 Objective-C 使用了引用计数)

For instance:

例如:

NSArray* ScoreBoard::getAllScores()
{ 
      ScoreBoard::ensureExistingTable();

      //Stack allocated
      SqliteWrapper sqlite("Scores.sqlite");

     NSArray* result = sqlite.RunQuery("SELECT * FROM Scores ORDER BY ID DESC");

     return result;
     //after this, the sqlite destructor is called
}

It is very nice that the Objective-C compiler allows you to merge C++. It can be extremely useful.

非常好,Objective-C 编译器允许您合并 C++。它非常有用。

Also

 void SqliteWrapper::Close()
 {
     sqlite3_close(db);
 }

as Vincent has pointed out, you have to finalize the statement. If you want keep the connection open, use finalize after each statement. Close out the connection the moment you are discarding the connection.

正如文森特所指出的,你必须完成声明。如果要保持连接打开,请在每个语句后使用 finalize。在您放弃连接的那一刻关闭连接。

This method works for me.

这个方法对我有用。

回答by asawadhesh singh

it is use for three methed 1.isert 2.update 3. delete.

它用于三个方法 1.isert 2.update 3. 删除。

-(NSMutableArray *)resultSet
-(void)insertWithTitle:(NSString *)title Body:(NSString *)body
-(BOOL)updateAtIndex:(int)index Title:(NSString *)title Body:(NSString *)body

NSMutableArray *result = [[[NSMutableArray alloc] initWithCapacity:0] autorelease];

FMResultSet *rs = [db executeQuery:[self SQL:@"SELECT * FROM %@" inTable:TABLE_NAME]];
while ([rs next]) {
    Record *tr = [[Record alloc] initWithIndex:[rs intForColumn:@"id"]
                                         Title:[rs stringForColumn:@"title"]
                                          Body:[rs stringForColumn:@"body"]];
    [result addObject:tr];
    [tr release];
}

[rs close];

2....

2....

return result;
[db executeUpdate:[self SQL:@"INSERT INTO %@ (title, body) VALUES (?,?)" inTable:TABLE_NAME], title, body];
if ([db hadError]) {
    NSLog(@"Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);

Delete record :

删除记录:

BOOL success = YES;
[db executeUpdate:[self SQL:@"DELETE FROM %@ WHERE id = ?" inTable:TABLE_NAME], [NSNumber numberWithInt:index]];
if ([db hadError]) {
    NSLog(@"Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);
    success = NO;
}
return success;

}