为了加速我在iOS6上的Sqlite3数据库上的数据库插入,我将插入包装在“BEGIN”和“END”命令中。 DB设置为以序列化模式运行。 有趣的是,我在执行“END”时遇到异常:错误表明数据库已被锁定。 嗯,我希望它被锁定,毕竟我在交易中据我所知。 有人可以解释什么条件可能导致这种行为吗?
答案 0 :(得分:2)
我发现了问题。要使序列化访问工作,您可能只有一个连接。在我的测试项目中,我忘了实现连接缓存。这样,我最终为每个数据库提供了很多(开放)连接。
答案 1 :(得分:0)
它必须是简单的东西,因为BEGIN / END命令没什么好看的。我努力重现你的问题(取消sqlite3_finalize
,消除BEGIN
等),但我不能。我知道生成该错误的唯一方法是多次打开数据库或使用后台队列执行某些操作。
您必须与我们分享源代码。也许您正在尝试重新打开数据库?或者你在背景队列上有什么东西可以拿着它?等
您提到以串行模式打开数据库。我是否推断出您有多个队列/线程在进行数据库操作?我个人通过一个串行队列来序列化我的数据库操作,我调度我的数据库调用,这保证了串行操作,因此我不必担心在特定模式下打开数据库。也许您可以描述以串行模式打开数据库的基本原理。
但是,无论如何,这是一个直接使用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);
}