FireDAC 在特定客户环境中表现不确定

问题描述 投票:0回答:1

我在使用 FireDAC 和 SQLite 的 Delphi 应用程序中遇到间歇性错误,专门在 Delphi 10 Seattle 中配置。

这个问题特别令人困惑,因为它只发生在一个特定的客户身上,表现出看似不确定的行为。通常,系统在重新启动后会恢复正常功能,但随后问题会意外地再次出现。我们无法在内部重现这些错误。它们只能通过使用 EurekaLog 来识别。

TFDConnection的配置:

  • 开启普通锁,支持多进程访问。
  • 预写式日志记录已启用。
  • (LockWait := True) 启用锁等待,允许事务等待锁被释放。
  • (lmPessimistic) 根据LockWait的要求使用悲观锁定。

两个进程同时访问数据库:通常,一个进程写入,另一个进程读取。没有繁重的负载,并且非常罕见的并发写入尝试可以通过锁等待设置有效管理。

此处显示的示例仅适用于读取操作。

问题

  1. 锁定模式、WAL 或其他等特定配置设置是否会导致这些错误?
  2. FireDAC 或 SQLite 参数是否有任何调整可能有助于在高负载条件或特定环境因素下稳定应用程序? (自动关闭、关闭前?)

示例 1 - 获取行

目标: 使用带有一个变量的准备好的语句来获取 SOP 实例 UID 的排序列表。

  Query := FQuerySortImagesByInstanceNoAsc;
  try
    begin
      Query.ParamByName('series_iuid').Value := SeriesInstanceUID;
      Query.Open;
      while not Query.Eof do
      begin
        SopInstUIDs.Add(Query.FieldByName(...).AsString);
        Query.Next;
      end;
    end;
  finally
    Query.Close;
  end;

失败于

Query.Next

ExceptionClass: EFDException
ExceptionMessage: [FireDAC][Phys][SQLITE]-311. Command must be open for fetching.

----------------------------------------------------------------------------------------------------------------------------------------------------------------
|Methods |Details|Stack           |Address         |Module      |Offset          |Unit                |Class                   |Procedure/Method    |Line      |
----------------------------------------------------------------------------------------------------------------------------------------------------------------
|*Exception Thread: ID=136748; Parent=131140; Priority=0                                                                                                       |
|Class=TQueryThread; Name=[Unnamed thread] Kind: TThread. Thread function: ...
|DeadLock=0; Wait Chain=                                                                                                                                       |
|Comment=                                                                                                                                                      |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------|
|7FFFFFFE|04     |0000000000000000|0000000000EC87A7|App.exe |0000000000AC87A7|FireDAC.Stan.Error  |                        |FDException         |189[27]   |
|00000020|04     |000000000D27EF68|000000000107C1B1|App.exe |0000000000C7C1B1|FireDAC.Phys        |TFDPhysCommand          |FetchBase           |8661[17]  |
|00000020|04     |000000000D27F018|000000000107B804|App.exe |0000000000C7B804|FireDAC.Phys        |TFDPhysCommandAsyncFetch|Execute             |8540[1]   |
|00000020|04     |000000000D27F048|00000000010AAACA|App.exe |0000000000CAAACA|FireDAC.Stan.Async  |TFDStanAsyncExecutor    |ExecuteOperation    |175[6]    |
|00000020|04     |000000000D27F0A8|00000000010AAFE5|App.exe |0000000000CAAFE5|FireDAC.Stan.Async  |TFDStanAsyncExecutor    |Run                 |270[12]   |
|00000020|04     |000000000D27F158|0000000001070964|App.exe |0000000000C70964|FireDAC.Phys        |TFDPhysCommand          |ExecuteTask         |6575[21]  |
|00000020|04     |000000000D27F1E8|000000000107C919|App.exe |0000000000C7C919|FireDAC.Phys        |TFDPhysCommand          |Fetch               |8751[2]   |
|00000020|04     |000000000D27F268|00000000010F302E|App.exe |0000000000CF302E|FireDAC.Comp.Client |TFDCustomCommand        |Fetch               |7032[11]  |
|00000020|04     |000000000D27F388|00000000010F54A7|App.exe |0000000000CF54A7|FireDAC.Comp.Client |TFDCustomTableAdapter   |Fetch               |7801[3]   |
|00000020|04     |000000000D27F3C8|00000000010FAB3E|App.exe |0000000000CFAB3E|FireDAC.Comp.Client |TFDAdaptedDataSet       |DoFetch             |9957[3]   |
|00000020|04     |000000000D27F408|00000000010C1CB2|App.exe |0000000000CC1CB2|FireDAC.Comp.DataSet|TFDDataSet              |InternalFetchRows   |4485[25]  |
|00000020|04     |000000000D27F488|00000000010BF0C5|App.exe |0000000000CBF0C5|FireDAC.Comp.DataSet|TFDDataSet              |GetRecord           |3551[16]  |
|00000020|04     |000000000D27F4D8|0000000000EBA653|App.exe |0000000000ABA653|Data.DB             |TDataSet                |GetNextRecord       |13812[9]  |
|00000020|04     |000000000D27F518|0000000000EBB272|App.exe |0000000000ABB272|Data.DB             |TDataSet                |MoveBy              |14183[16] |
|00000020|04     |000000000D27F578|0000000000EBB4CE|App.exe |0000000000ABB4CE|Data.DB             |TDataSet                |Next                |14227[3]  |
|00000020|04     |000000000D27F5A8|0000000001242159|App.exe |0000000000E42159|SQLiteConnection    |TSQLiteConnection       |SortImagesBySortType|577[26]   |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------|

示例 2 - 计数

目标: 使用带有一个变量的准备好的语句确定属于当前系列的文件数。

  Query := FQueryGetFileCountSeries;
  try
    Query.ParamByName('series_iuid').Value := SeriesInstanceUID;
    Query.Open;
    Result := Query.Fields[0].AsInteger;
  finally
    Query.Close;
  end;

失败于

Query.Close

ExceptionClass: EInvalidPointer
ExceptionMessage: Application made attempt to free invalid or unknown memory block: $000000000F6B02B0 DATA [?] 0 bytes.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|Methods |Details|Stack           |Address         |Module      |Offset          |Unit                |Class              |Procedure/Method                   |Line       |
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|*Exception Thread: ID=139204; Parent=0; Priority=0                                                                                                                       |
|Class=; Name=MAIN                                                                                                                                                        |
|DeadLock=0; Wait Chain=                                                                                                                                                  |
|Comment=                                                                                                                                                                 |
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|7FFFFFFE|04     |0000000000000000|0000000000412285|App.exe |0000000000012285|System              |                   |_UStrClr                           |24641[8]   |
|00000020|04     |000000000014DC38|0000000000412342|App.exe |0000000000012342|System              |                   |_UStrArrayClr                      |24786[4]   |
|00000020|04     |000000000014DC78|00000000004150DA|App.exe |00000000000150DA|System              |                   |_FinalizeArray                     |31726[24]  |
|00000020|04     |000000000014DCC8|0000000000414FE0|App.exe |0000000000014FE0|System              |                   |_FinalizeRecord                    |31577[18]  |
|00000020|04     |000000000014DD18|000000000040EF1E|App.exe |000000000000EF1E|System              |TObject            |CleanupInstance                    |16368[8]   |
|00000020|04     |000000000014DD58|000000000040ED3B|App.exe |000000000000ED3B|System              |TObject            |FreeInstance                       |16186[1]   |
|00000020|04     |000000000014DD88|000000000040F82E|App.exe |000000000000F82E|System              |                   |_ClassDestroy                      |17536[1]   |
|00000020|04     |000000000014DDB8|0000000000E9D8F8|App.exe |0000000000A9D8F8|Data.DB             |TField             |Destroy                            |4809[9]    |
|00000020|04     |000000000014DDF8|000000000040EE65|App.exe |000000000000EE65|System              |TObject            |Free                               |16255[5]   |
|00000020|04     |000000000014DE28|0000000000E9CB6A|App.exe |0000000000A9CB6A|Data.DB             |TFields            |ClearBase                          |4487[14]   |
|00000020|04     |000000000014DE88|0000000000E9CC46|App.exe |0000000000A9CC46|Data.DB             |TFields            |ClearAutomatic                     |4506[1]    |
|00000020|04     |000000000014DEB8|0000000000EB717E|App.exe |0000000000AB717E|Data.DB             |TDataSet           |DestroyFields                      |12782[1]   |
|00000020|04     |000000000014DEF8|00000000010BD795|App.exe |0000000000CBD795|FireDAC.Comp.DataSet|TFDDataSet         |InternalClose                      |3068[21]   |
|00000020|04     |000000000014DF78|00000000010F9C93|App.exe |0000000000CF9C93|FireDAC.Comp.Client |TFDAdaptedDataSet  |InternalClose                      |9628[2]    |
|00000020|04     |000000000014DFA8|00000000010FD3BD|App.exe |0000000000CFD3BD|FireDAC.Comp.Client |TFDRdbmsDataSet    |InternalClose                      |11018[3]   |
|00000020|04     |000000000014DFF8|0000000000EB631C|App.exe |0000000000AB631C|Data.DB             |TDataSet           |CloseCursor                        |12528[6]   |
|00000020|04     |000000000014E038|00000000010BD03E|App.exe |0000000000CBD03E|FireDAC.Comp.DataSet|TFDDataSet         |CloseCursor                        |2939[3]    |
|00000020|04     |000000000014E078|0000000000EB60BA|App.exe |0000000000AB60BA|Data.DB             |TDataSet           |SetActive                          |12480[22]  |
|00000020|04     |000000000014E0C8|00000000010B881C|App.exe |0000000000CB881C|FireDAC.Comp.DataSet|TFDDataSet         |SetActive                          |1581[7]    |
|00000020|04     |000000000014E0F8|0000000000EB5DB1|App.exe |0000000000AB5DB1|Data.DB             |TDataSet           |Close                              |12431[1]   |
|00000020|04     |000000000014E128|000000000124D247|App.exe |0000000000E4D247|SQLiteConnection    |TSQLiteConnection  |GetFileCountSeries                 |1582[8]    |
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
sqlite delphi firedac delphi-10-seattle
1个回答
0
投票

我使用

TThread.Synchronize
将相关调用移至主线程,这解决了问题。

© www.soinside.com 2019 - 2024. All rights reserved.