我的场景很简单,我有一个进程生成一些数据并将其放入数据库(当前最后一个完成后5秒)然后有任意数量的进程打开连接以读取单个记录以供使用内部(最后一个完成后5秒)。数据库位于本地驱动器上,操作系统是Windows Server 2012 R2。
使用阅读器进程我偶尔会在连接到sqlite数据库时收到错误,当连接打开时会抛出[FireDAC][Phys][SQLite] ERROR: unable to close due to unfinalized statements or unfinished backups
异常并且我对原因和含义感到困惑错误消息(在打开连接的情况下)。
我的连接是这样创建的(在读者和编写器应用程序中):
connection := TFDConnection.Create(nil);
connection.Params.Add('DriverID=SQLite');
connection.Params.Add('Database=' + aDatabasePath);
connection.Params.Add('OpenMode=CreateUTF16');
connection.Params.Add('LockingMode=Normal');
connection.Params.Add('JournalMode=WAL');
connection.Params.Add('Synchronous=Full');
connection.Params.Add('UpdateOptions.LockWait=True');
connection.Params.Add('BusyTimeout=30000');
connection.Params.Add('SQLiteAdvanced=temp_store=MEMORY');
connection.Params.Add('SQLiteAdvanced=page_size=4096');
connection.Params.Add('SQLiteAdvanced=auto_vacuum=FULL');
connection.Open();
在调查被抛出的EFDDBEngineException
之后,错误列表中只有一个错误,其中包含ErrorCode=5
sqlite errorcodes和sqlite result codes所说的SQLITE_BUSY
1}}错误。
调查callstack
ntdll.dll KiUserExceptionDispatcher
FireDAC.Phys.SQLite TFDPhysSQLiteConnection.InternalDisconnect
FireDAC.Phys TFDPhysConnection.ConnectBase
ntdll.dll KiUserExceptionDispatcher
FireDAC.Phys.SQLiteWrapper TSQLiteStatement.PrepareBase
FireDAC.Phys.SQLiteWrapper TSQLiteStatement.Prepare
FireDAC.Phys.SQLiteWrapper TSQLiteStatement.Prepare
FireDAC.Phys.SQLite TFDPhysSQLiteConnection.InternalExecuteDirect
FireDAC.Phys.SQLite SetPragma
FireDAC.Phys.SQLite TFDPhysSQLiteConnection.InternalConnect
FireDAC.Phys TFDPhysConnection.ConnectBase
FireDAC.Phys TFDPhysConnection.DoConnect
FireDAC.Phys TFDPhysConnection.Open
FireDAC.Comp.Client TFDCustomConnection.DoInternalLogin
FireDAC.Comp.Client TFDCustomConnection.DoLogin
FireDAC.Comp.Client TFDCustomConnection.DoConnect
Data.DB TCustomConnection.SetConnected
FireDAC.Comp.Client TFDCustomConnection.SetConnected
Data.DB TCustomConnection.Open
显然不喜欢TSQLiteStatement.PrepareBase
中发生的事情,然后导致TFDPhysConnection.ConnectBase
尝试清理连接创建的任何一点,但是未完成的语句将在哪里?
I Close()
和Free()
每个TFDQuery以及我完成后的连接。
我缺少什么?
旁注,因为这对我来说是一个问题。一旦发生错误,WAL和SHM文件不会折叠到数据库文件中,如果我尝试在指向共享文件夹中的数据库的调试器下运行我的开发机器上的读取器应用程序,它在尝试打开时完全锁定一个连接和结束所有其他读者和编写器进程没有解锁它然后我需要重新启动我的开发机器。