0

最近,我为我正在处理的 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 TABLEorINSERT语句保存到磁盘?

阅读文档后,似乎除非明确设置,否则journal_modesqlite 数据库的 应设置为DELETE. 如果这是真的,我应该在提交完成后不再有 -journal 文件。有什么方法可以通过 c API 进行测试吗?

由于我如何使用我的数据库包装器来处理几个不同的数据库文件,我也被引导相信代码是按功能顺序排列的。成功开始并提交事务后,BEGIN 和 COMMIT 状态码始终为 0,表示SQLITE_OK. 这种奇怪的行为只发生在我在尝试COMMIT任何更改之前只插入一条记录的情况下。

我从默认 sqlite 配置更改的唯一其他选项是页面大小 ( PRAGMA cipher_page_size = 4096)。页面大小已经过调整,以帮助提高我也与此包装器一起使用的一些其他大型数据库的性能。删除我对页面大小的修改并不能解决问题。

最后,我注意到如果我一起删除交易,我根本不会遇到这个问题。最好,我想保留事务以提高性能,但让它不持久化我的数据会破坏数据库的目的。

有没有人知道为什么会发生这种情况或者我可以尝试什么?

提前致谢。

4

0 回答 0