FireDac没有简单的方法来支持螺纹连接。默认情况下,FireDac连接不是线程安全。这意味着,如果您尝试同时使用相同的连接在数据库中使用多个线程进行操作,则可以(通常)会导致例外。该库通过连接池包含了解决方案,从而使其更容易。
连接池假定您正在使用连接定义。这很容易实现,即使默认未使用,甚至动态地实现。可以在应用程序的主要形式中找到一个示例。连接池可用于请求连接。池检查线程是否已经存在连接和给定的连接定义。如果是这样,将返回连接,如果没有,则将创建和注册。为了在申请执行过程中保持正确的态度,已经添加了单身人士的实现。
您可以在连接池中注册默认连接定义的名称,因此您无需每次指定它。请求连接的线程的ID也可以由池自动确定。
还有一个用于使用连接池的线程的基类。还包括一个使用此基类的示例,并以应用程序的主要形式进行处理。
在您的项目或数据模块中包含ThreadedConnections.Singleton 。调用SetConnectionPoolDefaults方法以初始化连接池的单例。例如:
SetConnectionPoolDefaults('SQLite', 'MainDatabase');
在此示例中, 'SQLite'是驱动程序和'MainDatabase'连接定义的名称。
如果不使用连接定义,则可以使用与连接相同的参数轻松地动态创建它们。以下示例假设有一个称为dmDatabase.DbConnection的连接。
const DefinitionName = 'MainDatabase';
var Definition := FDManager.ConnectionDefs.FindConnectionDef(DefinitionName);
if not Assigned(Definition) then
begin
var Connection := dmDatabase.DbConnection;
FDManager.AddConnectionDef(DefinitionName, Connection.ActualDriverID, Connection.Params);
end;
使用Singleton时,可以使用GetConnectionPool函数检索其实例。此功能可在ThreadedConnections.Singleton中可用。Singleton单元。池可以访问许多GetConnection函数来请求连接。 NO参数变体假设您正在为默认连接定义和当前线程执行此操作。这也可以是主线程。
var Pool := GetConnectionPool;
var DefaultConnection := Pool.GetConnection;
var SpecificConnection := Pool.GetConnection('FinancialDatabase', Self.ThreadID);
您可以将TThreadedConnectionThread用作线程的超类。该课程期望创建的连接池的实例。它提供了标准功能,可以轻松获得子类中的连接。一个示例可以在ThreadedConnections.Example.Threads中找到。当然,也可以将超级阶级用作在您自己的超级类别中实现的示例。
这是一个示例,如何在使用TThreadedConnectionThread用作超类时使用它:
TMyDatabaseThread = class(TThreadedConnectionThread)
protected
procedure Execute; override;
end;
TMyDatabaseThread.Execute;
begin
var Query := TFDQuery.Create;
try
Query.Connection := GetConnection;
...
finally
Query.Free;
end;
end;
var Thread := TMyDatabaseThread.Create(True, GetConnectionPool);
Thread.Start;