最近,我已将BEGIN
和COMMIT
事务添加到针对我正在处理的iOS应用程序的sqlcipher sqlite3数据库的所有数据库调用中。
我通过以下方法做到这一点:
#define kTRANSACTION_BEGIN @"BEGIN"
#define kTRANSACTION_COMMIT @"COMMIT"
-(void)transactionBegin
{
int status = sqlite3_exec(self.Database, kTRANSACTION_BEGIN.UTF8String, NULL, NULL, NULL);
NSLog(@"BEGIN Status = %i", status);
}
-(void)transactionEnd
{
char* errorMessage;
int status = 0;
status = sqlite3_exec(self.Database, kTRANSACTION_COMMIT.UTF8String, NULL, NULL, &errorMessage);
NSLog(@"COMMIT Status = %i", status);
if (status != SQLITE_OK) {
NSLog(@"ERROR: SQL Error closing transaction (%i): %s\n %s",status, errorMessage ,sqlite3_errmsg(self.Database));
}
}
在打开(并设置PRAGMA)之后和关闭数据库连接之前,会直接调用这些方法。
这两个似乎都成功执行。但是,在检查数据库的位置时,db.sqlite文件保持0字节,db.sqlite-journal文件为512字节。查询再次运行,数据库继续成功执行,直到应用程序关闭,然后插入的所有数据都将丢失。为什么我的COMMIT
未将我的CREATE TABLE
或INSERT
语句保留在磁盘上?
阅读文档后,除非明确设置,否则sqlite数据库的journal_mode
应设置为DELETE
。如果这是真的,我应该在提交完成后不再有-journal文件。我可以通过c API进行测试吗?
由于我使用数据库包装器处理几个不同的数据库文件,我也被认为代码处于功能顺序。成功启动和提交事务后,BEGIN和COMMIT状态代码始终为0,表示SQLITE_OK
。这种奇怪的行为只发生在我在尝试COMMIT
任何更改之前只插入一条记录的情况下。
我从默认sqlite配置中更改的唯一其他选项是页面大小(PRAGMA cipher_page_size = 4096
)。已调整页面大小以帮助提高我也使用此包装器的一些其他大型数据库的性能。删除我对页面大小的修改无法解决问题。
最后,我注意到如果我一起删除所有交易,我根本不会遇到这个问题。最好是,我想在交易中留下性能提升,但如果没有持久保存我的数据,则会失去数据库的目的。
有人会有任何关于为什么会发生这种情况或我能尝试的其他事情的想法吗?
提前致谢。