最近,我为我正在处理的 iOS 应用程序添加了针对我的 sqlcipher sqlite3 数据库的所有数据库调用BEGIN
和事务。COMMIT
我通过以下方法做到这一点:
#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
orINSERT
语句保存到磁盘?
阅读文档后,似乎除非明确设置,否则journal_mode
sqlite 数据库的 应设置为DELETE
. 如果这是真的,我应该在提交完成后不再有 -journal 文件。有什么方法可以通过 c API 进行测试吗?
由于我如何使用我的数据库包装器来处理几个不同的数据库文件,我也被引导相信代码是按功能顺序排列的。成功开始并提交事务后,BEGIN 和 COMMIT 状态码始终为 0,表示SQLITE_OK
. 这种奇怪的行为只发生在我在尝试COMMIT
任何更改之前只插入一条记录的情况下。
我从默认 sqlite 配置更改的唯一其他选项是页面大小 ( PRAGMA cipher_page_size = 4096
)。页面大小已经过调整,以帮助提高我也与此包装器一起使用的一些其他大型数据库的性能。删除我对页面大小的修改并不能解决问题。
最后,我注意到如果我一起删除交易,我根本不会遇到这个问题。最好,我想保留事务以提高性能,但让它不持久化我的数据会破坏数据库的目的。
有没有人知道为什么会发生这种情况或者我可以尝试什么?
提前致谢。