我该如何处理sqlite错误?

时间:2010-05-16 06:17:11

标签: c sqlite

我有一个长期运行的应用程序,用C和C ++混合编写,用于在sqlite中存储数据。

虽然我确信提交的数据仍然可用(除非机械故障)和未提交的数据不会,但我不清楚我能用这种中间状态做些什么。

我在事务中执行大量插入操作然后提交它。当给定语句发生错误时,我可以安排在将来的某个时间点尝试它。听起来像一些错误可能会隐式地回滚我的事务(如果这是真的,这将是不可取的。)

更大的问题是当我的提交本身失败时会发生什么。目前,我只是继续重试它,直到它工作。我希望无论导致我的提交失败的原因都可能导致回滚失败。

在这种情况下,建议的错误处理机制是什么?

4 个答案:

答案 0 :(得分:1)

在COMMIT上,如果看到SQLITE_BUSY错误,则应重新尝试 COMMIT。它可能会奏效。更好的是,安装一个忙碌的处理程序回调 处理SQLITE_BUSY。

COMMIT失败的另一个原因是延迟外键 违反。如果发生这种情况,您可以修复FK违规和 然后COMMIT。很难看到无人操作的应用程序这样做。

你应该放弃的其他错误和ROLLBACK 事务。

如果发生IO或OOM错误,则当前事务可能是 回滚。这是因为某些IO或OOM错误会离开SQLite 不确定其内部数据结构是否匹配 什么是在磁盘上。如果我们要继续这一点 数据库可能会损坏。

您可以测试事务是否已回滚 由SQLite使用sqlite3_get_autocommit()API。

如果在COMMIT期间发生IO或OOM错误,则事务可能会发生 仍然承诺。例如,如果可能发生这种情况 用户碰巧将存储卡从相机中撕下来就像 交易已提交。通常不可能知道 如果数据在没有读取的情况下进入持久性媒体 db并在应用程序级别进行检查。

答案 1 :(得分:0)

无论您尝试多少次,在不可为空的列中插入空值都不太可能成功。

您的问题没有单一的解决方案。例如,如果您违反数据库约束,则应在再次尝试之前更改数据。如果您没有剩余内存/磁盘空间 - 请释放一些并重试。

我想您需要了解有关交易和ACID属性的更多信息。

答案 2 :(得分:0)

数据库是明确设计的,因此数据始终是已提交或未提交。提交数据时,它不会被任意丢失,因为它在永久存储上(嗯,在磁盘文件中,这是一个很好的近似)。如果您正在进行手动事务管理(听起来像这样),那么在被要求之前,数据库不会 COMMIT或ROLLBACK。可以处理语句中的错误而不会丢失已经完成的任何操作。

如果您处于无法执行COMMIT或ROLLBACK的状态,那么您就陷入了困境。如果是因为你的内存或磁盘空间不足(或配额),那么你已经错误地配置了应用程序,你应该先修复它。

您也可能想要考虑限制交易的长度,以便在发生故障时减少灾难性(就恢复工作而言)。

答案 3 :(得分:0)

虽然我不同意早期的答案,因为SQLite绝对会遇到瞬态错误,只允许你通过重试几次成功执行COMMIT,他们确实有一个很好的观点,不适用于所有错误。不要忘记实施重试限制,也许还要检查失败的原因,而不是盲目地重试。