我有一个销售点程序,已为一些客户工作了约4年,因为我需要它离线工作,我选择使用SQLite,这对我来说非常好.在我的一个客户端,停电后,当天已注册的数据“消失”,数据库停留在前一天的状态,甚至自动增量字段也回来了。我使用SQLite版本3和使用journal_mode = DELETE。我想知道是否有什么阻止了这个问题,或者是什么导致了这个问题?
9wbgstp71#
Sqlite被设计为即使在断电后也能保持数据库的一致状态。断电后第一次访问数据库时,Sqlite必须发现存在包含未提交事务的日志文件,并将其回滚到事务的开始位置。从您的问题描述来看,显然未提交事务的开始是在一天的开始。这似乎表明程序在启动时打开事务处理,在正确关闭程序时关闭事务处理。这意味着所有更改都存储在回退日记帐中,并且只有在正常关闭程序后才写入数据库。如果这是真的,您需要更改程序,使其仅在有一些数据要写入时才打开事务(使用开始TRANSACTION),并在完成后立即关闭事务(使用COMMIT)。如果您认为您的程序已经在这样做了,那么我将检查是否有一个查询或条件发出了开始TRANSACTION,但后面没有任何COMMIT。为了帮助您调试程序,请注意,当journal_mode设置为DELETE时,日记帐文件将在任何事务结束时删除。因此,如果您在任何时候看到与数据库文件位于同一目录中的文件与数据库文件具有相同的名称,只是附加了8个字符“-journal”,这意味着有一个打开的事务等待被提交或回滚。2这个文件应该只在长时间写事务或程序崩溃时保存。
1条答案
按热度按时间9wbgstp71#
Sqlite被设计为即使在断电后也能保持数据库的一致状态。断电后第一次访问数据库时,Sqlite必须发现存在包含未提交事务的日志文件,并将其回滚到事务的开始位置。
从您的问题描述来看,显然未提交事务的开始是在一天的开始。
这似乎表明程序在启动时打开事务处理,在正确关闭程序时关闭事务处理。这意味着所有更改都存储在回退日记帐中,并且只有在正常关闭程序后才写入数据库。
如果这是真的,您需要更改程序,使其仅在有一些数据要写入时才打开事务(使用开始TRANSACTION),并在完成后立即关闭事务(使用COMMIT)。
如果您认为您的程序已经在这样做了,那么我将检查是否有一个查询或条件发出了开始TRANSACTION,但后面没有任何COMMIT。
为了帮助您调试程序,请注意,当journal_mode设置为DELETE时,日记帐文件将在任何事务结束时删除。因此,如果您在任何时候看到与数据库文件位于同一目录中的文件与数据库文件具有相同的名称,只是附加了8个字符“-journal”,这意味着有一个打开的事务等待被提交或回滚。2这个文件应该只在长时间写事务或程序崩溃时保存。