尝试使用多个进程打开连接时出现SQLite异常

时间:2016-10-17 05:06:12

标签: sqlite delphi delphi-10-seattle firedac

我的场景很简单,我有一个进程生成一些数据并将其放入数据库(当前最后一个完成后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 errorcodessqlite 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文件不会折叠到数据库文件中,如果我尝试在指向共享文件夹中的数据库的调试器下运行我的开发机器上的读取器应用程序,它在尝试打开时完全锁定一个连接和结束所有其他读者和编写器进程没有解锁它然后我需要重新启动我的开发机器。

0 个答案:

没有答案