为什么';在我关闭应用程序之前,我的SQLite数据库不会添加数据吗?
我的Delphi应用程序使用FireDac和SQLite数据库。我注意到更新保存在一个日志文件中,数据库文件在我关闭应用程序之前不会真正更新 应用程序正在对数据库进行大量“批量更新”。每个单独的更新都在TFDQuery.StartTransaction中。。。提交对。尽管如此,似乎所有更新都保存在日志文件中,直到应用程序结束为什么';在我关闭应用程序之前,我的SQLite数据库不会添加数据吗?,sqlite,delphi,firedac,Sqlite,Delphi,Firedac,我的Delphi应用程序使用FireDac和SQLite数据库。我注意到更新保存在一个日志文件中,数据库文件在我关闭应用程序之前不会真正更新 应用程序正在对数据库进行大量“批量更新”。每个单独的更新都在TFDQuery.StartTransaction中。。。提交对。尽管如此,似乎所有更新都保存在日志文件中,直到应用程序结束 try Query.Connection := FDConnection1; FDConnection1.Open; FDConnection1.StartTr
try
Query.Connection := FDConnection1;
FDConnection1.Open;
FDConnection1.StartTransaction;
Query.SQL.Text := 'select 1 from t_Manufacturers where m_Name = ' + QuotedStr(ManString);
Query.Open;
if Query.RecordCount = 0 then begin
{ not found, so add }
Query.SQL.Text := 'insert into t_Manufacturers (m_Name, m_ManUID) values (:Name, null)';
Query.ParamByName('Name').AsString := ManString;
Query.ExecSQL;
{ save m_ManUID for logging }
Query.SQL.Text := 'select m_ManUID from t_Manufacturers where m_Name = ' + QuotedStr(ManString);
Query.Open;
end;
Result := Query.FieldByName(m_ManUID).AsInteger;
FDConnection1.Commit;
except
on E : EDatabaseError do begin
MessageDlg('Database error adding manufacturer: ' + E.Message, mtError, [mbOk], 0);
FDConnection1.Rollback;
end;
如何在每批更新之后而不是在应用程序完成时强制SQLite更新数据库
我尝试将SQLite db更改为WAL,但同样的情况也发生了
尽管使用了“StartTransaction”和“Commit”,但数据仍保留在日志中,直到应用程序结束
try
Query.Connection := FDConnection1;
FDConnection1.Open;
FDConnection1.StartTransaction;
Query.SQL.Text := 'select 1 from t_Manufacturers where m_Name = ' + QuotedStr(ManString);
Query.Open;
if Query.RecordCount = 0 then begin
{ not found, so add }
Query.SQL.Text := 'insert into t_Manufacturers (m_Name, m_ManUID) values (:Name, null)';
Query.ParamByName('Name').AsString := ManString;
Query.ExecSQL;
{ save m_ManUID for logging }
Query.SQL.Text := 'select m_ManUID from t_Manufacturers where m_Name = ' + QuotedStr(ManString);
Query.Open;
end;
Result := Query.FieldByName(m_ManUID).AsInteger;
FDConnection1.Commit;
except
on E : EDatabaseError do begin
MessageDlg('Database error adding manufacturer: ' + E.Message, mtError, [mbOk], 0);
FDConnection1.Rollback;
end;
没有错误消息或问题。如果应用程序完成正常,数据库将按预期更新,因此我很高兴我的编程和SQL在这方面正是我所需要的。您使用的是
FDConnection1.StartTransaction
在此状态条件下,事务仍在内存(缓存)中,没有结束。因此,您需要使用commit
命令结束事务,如FDConnection1.commit代码>很可疑的是,“似乎所有更新都保存在日志文件中,直到应用程序结束”。SQLite3非常认真地编写数据——比我所知道的大多数DB引擎都要认真。检查一下
我怀疑你对日志文件的存在有些困惑。事务完成后,日志文件仍保留在磁盘上,以便进行任何新的写入操作。但是数据实际上是写在主文件中的
只需写入一些数据,然后在关闭应用程序之前杀死它(使用任务管理器)。然后重新打开文件(重新启动应用程序):我几乎可以肯定你会看到正确存储的数据
FireDAC使用默认日志模式“作弊”,以获得最佳性能。它使用了一些可能会让人困惑的默认值。如所述:将锁定模式设置为正常,以启用共享数据库访问。将Synchronous设置为Normal或Full以使提交的数据对其他人可见。好的,我回到了基础知识,编写了一个测试应用程序,所有数据库活动仅限于通过单击按钮触发的单个过程。在该过程中,我使用for循环向表中添加了多行
for循环被StartTransaction和Commit调用包围。在调试器中运行代码时,日志文件将在第一次调用ExecSQL时创建。但是,在循环完成并调用Commit之后,文件仍保留在那里
只有在过程结束时调用Close时,才会更新数据库并删除日志文件
procedure TForm1.Button1Click(Sender: TObject);
var
Query : TFDQuery;
Index : Integer;
begin
FDConnection1.DriverName := 'SQLite';
FDConnection1.Params.Values['Database'] := 'C:\Testing\test.db';
FDConnection1.Open;
Query := TFDQuery.Create(nil);
Query.Connection := FDConnection1;
try
FDConnection1.StartTransaction;
for Index := 1 to 10 do begin
Query.SQL.Text := 'insert into Table1 (Name, IDNum) values (:Name, :IDNum)';
Query.ParamByName('Name').AsString := 'Test_Manufacturer_' + IntToStr(Index);
Query.ParamByName('IDNum').AsInteger := Index;
Query.ExecSQL;
end;
FDConnection1.Commit;
except
on E : EDatabaseError do begin
MessageDlg('Database error adding manufacturer: ' + E.Message, mtError, [mbOk], 0);
FDConnection1.Rollback;
end;
end;
Query.Destroy;
FDConnection1.Close;
end;
我怀疑我的应用程序中打开了另一个数据库连接,这可能会在应用程序关闭之前停止更新。但是,我仍然不理解为什么在事务块末尾调用Commit没有更新数据库。谢谢您的响应。我已经有了FDConnection1.Commit-就在Exception块之前。对不起,Steve,删除了我对你文章的回答。你完全正确,是我的错。似乎是SQLLite的一个问题。请看:SQLLite驱动程序默认配置为提供高性能。查看“使用SQLite数据库”一节的位置4-6可能会有所帮助。如果不是alreadyDave,请将Options属性中的锁定模式设置为lmNormal-谢谢。我检查过,它被设置为lmNormal。这种行为甚至在中有记录。如果locking_mode
设置为EXCLUSIVE
,则在事务结束时不会删除回滚日志,这在FireDAC.Arnaud中是默认设置的-谢谢您。我现在觉得有点傻。我尝试了你的建议,并在调用“提交”后立即终止了我的应用程序。正如您所建议的,日志文件仍然存在,但数据已添加到数据库中。我被一个打开的浏览器窗口愚弄了,它显示了我的应用程序运行时日志文件的存在。Peter-谢谢你。我以前见过这种情况,但第二次阅读帮助我更好地理解了这一点。这种行为听起来像是在创建保存点。这似乎是在你已经有一笔交易未结的情况下开始交易的时候。我会寻找迷路的StartTransaction
呼叫。或者你正在使用Wal模式,这是正常行为。Shawn,谢谢你的回复。我会仔细检查我的代码,看看是否是这样。Shawn,只是确认一下,WAL没有被使用。