为了加快上SQLITE3 DB在iOS6的我的数据库插入,我在包裹“BEGIN”和“END”命令插入。 该数据库被设定为串行模式下运行。 有趣的是执行“END”当我得到一个异常:错误说DB被锁定。 好了,我希望它被锁定了,毕竟我在一个事务中是据我可以告诉。 有人能解释什么条件下可能会导致这种行为?
Answer 1:
我发现这个问题。 为了使序列化访问工作,你可能只有一个连接。 在我的测试项目中,我忘了实现连接高速缓存。 这样,我结束了对每个数据库比较多的(开放)的连接。
Answer 2:
这一定是简单的东西,因为没有什么花哨的约BEGIN / END命令。 我努力重现您的问题(消除sqlite3_finalize
,消除BEGIN
等),但我不能。 我知道要产生错误的唯一方法是多次打开数据库或做背景队列的东西。
你必须与我们分享源代码。 也许你正在试图重新打开数据库? 或者你有可能被拿着一份背景队列的东西吗? 等等。
你提到的串行模式打开数据库。 难道我的推断,你有多个队列/线程执行数据库操作? 我个人连载我的数据库操作由具有串行队列,我派我的数据库调用,保证连续作业,因而我从来不担心在特定模式下打开数据库。 也许你可以描述为以串行方式打开数据库的基本原理。
但是,不管怎样,这里使用的样本insert方法sqlite
直接调用(虽然我承认,我通常使用FMDB消除难看这样的代码):
- (void)sqlInsert
{
sqlite3_stmt *statement;
sqlite3 *database = NULL;
int rc;
char *errmsg;
if ((rc = [self openDatabase:&database]) != SQLITE_OK) // my open does the necessary parsing of the path, copying files, etc.
{
NSLog(@"%s database open error %d", __FUNCTION__, rc);
return;
}
sqlite3_exec(database, "BEGIN", NULL, NULL, &errmsg);
if (errmsg != NULL)
{
NSLog(@"%s exec BEGIN SQL error '%s'", __FUNCTION__, errmsg);
sqlite3_free(errmsg);
}
const char *insertSql = "INSERT INTO CONTACTS (name, address, phone) VALUES (?, ?, ?)";
if (sqlite3_prepare_v2(database, insertSql, -1, &statement, NULL) != SQLITE_OK)
NSLog(@"%s prepare SQL error '%s' (%1d)", __FUNCTION__, sqlite3_errmsg(database), sqlite3_errcode(database));
if (sqlite3_bind_text(statement, 1, [self.contactName.text UTF8String], -1, NULL) != SQLITE_OK)
NSLog(@"%s bind contactName error '%s'", __FUNCTION__, sqlite3_errmsg(database));
if (sqlite3_bind_text(statement, 2, [self.contactAddress.text UTF8String], -1, NULL) != SQLITE_OK)
NSLog(@"%s bind contactAddress error '%s'", __FUNCTION__, sqlite3_errmsg(database));
if (sqlite3_bind_text(statement, 3, [self.contactPhone.text UTF8String], -1, NULL) != SQLITE_OK)
NSLog(@"%s bind contactPhone error '%s'", __FUNCTION__, sqlite3_errmsg(database));
if (sqlite3_step(statement) == SQLITE_DONE)
NSLog(@"%s Contact added", __FUNCTION__);
else
NSLog(@"%s step SQL error '%s' (%1d)", __FUNCTION__, sqlite3_errmsg(database), sqlite3_errcode(database));
sqlite3_finalize(statement);
sqlite3_exec(database, "END", NULL, NULL, &errmsg);
if (errmsg != NULL)
{
NSLog(@"%s exec END SQL error '%s'", __FUNCTION__, errmsg);
sqlite3_free(errmsg);
}
sqlite3_close(database);
}
文章来源: Sqlite database locked when executing “END”