失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Delphi 中 FireDAC 数据库连接(多线程)

Delphi 中 FireDAC 数据库连接(多线程)

时间:2020-08-07 03:19:04

相关推荐

Delphi 中 FireDAC 数据库连接(多线程)

参见:Delphi 中 FireDAC 数据库连接(总览)

本主题描述了如何在多线程环境下使用FireDAC。

一、概述

如果满足以下条件,FireDAC是线程安全的。

一个连接对象和所有与之相关的对象(如TFDQuery、TFDTransaction等)在每个时刻都由一个线程使用。

FDManager在线程开始之前被激活,通过设置FDManager.Active为True。

这意味着,在一个线程打开一个查询后,直到它的处理完成,应用程序不能在另一个线程中使用这个查询和连接对象。同样,在一个线程启动一个交易后,直到交易完成,应用程序不能在另一个线程中使用这个交易和连接对象。

这实际上意味着应用程序必须在所有线程中序列化对连接的访问,这并不是一种方便的技术。破坏这些规则可能会导致行为不当、AV错误和其他错误,例如SQL Server的错误 "连接正忙于处理另一条命令的结果"。

标准的简化方法是为每个线程创建和使用一个与数据库工作的专用连接对象。在这种情况下,不需要额外的序列化。例如,下面的代码在线程中执行DB任务。

typeTDBThread = class(TThread)protectedprocedure Execute; override;end;procedure TDBThread.Execute;varoConn: TFDConnection;oPrc: TFDQuery;beginFreeOnTerminate := False;oConn := TFDConnection.Create(nil);oConn.ConnectionDefName := 'Oracle_Pooled'; // see next sectionoPrc := TFDStoredProc.Create(nil);oPrc.Connection := oConn;tryoConn.Connected := True;oPrc.StoredProcName := 'MY_LONG_RUNNING_PROC';oPrc.ExecProc;finallyoPrc.Free;oConn.Free;end;end;// main application codevaroThread1, oThread2: TDBThread;beginFDManager.Active := True;...oThread1 := TDBThread.Create(False);oThread2 := TDBThread.Create(False);...oThread1.WaitFor;oThread1.Free;oThread2.WaitFor;oThread2.Free;end;

注意:对于上述情况,应用程序在后台运行一个单一的SQL查询,使用异步查询执行模式。一个多线程的应用程序可以在TFDManager.BeforeShutdown事件处理程序中关闭在后台线程中打开的连接,以避免可能的死锁。

二、连接池

费时的数据库交互操作之一是建立连接。在一个多线程的应用程序中,每个线程都会启动,建立一个连接,执行某个简短的任务并释放连接,重复的连接建立可能导致整个系统的性能下降。为了避免这种情况,应用程序可以使用连接池。

连接池只能通过设置Pooled=True来为持久化或私有连接定义启用。对于一个持久化的定义。

[Oracle_Pooled]DriverID=OraDatabase=ORA_920_APPUser_Name=ADDemoPassword=aPooled=True

或用于私有定义设置。

varoParams: TStrings;beginoParams := TStringList.Create;oParams.Add('Database=ORA_920_APP');oParams.Add('User_Name=ADDemo');oParams.Add('Password=a');oParams.Add('Pooled=True');FDManager.AddConnectionDef('Oracle_Pooled', 'Ora', oParams);.....................FDConnection1.ConnectionDefName := 'Oracle_Pooled';FDConnection1.Connected := True;

不能在TFDConnection.Params属性中指定额外的参数,因为所有池中的连接必须共享相同的连接参数。

将TFDConnection.Connected设置为True会从池中获取一个物理连接。将TFDConnection.Connected设置为False会将物理连接释放到池中,但保持连接的开放。要关闭和销毁所有池中的物理连接,应用程序可以调用TFDManager.CloseConnectionDef方法。

FDManager.CloseConnectionDef('Oracle_Pooled');

或通过调用关闭FireDAC驱动程序管理器。

FDManager.Close;

可以指定额外的连接定义参数来设置一个池:

关于Delphi 连接池的示例程序,请参见:

你可以在以下位置找到TFDConnection/Pooling示例项目。

Start | Programs | Embarcadero RAD Studio Sydney | Samples,然后导航到。

Object Pascal\DataBase\FireDAC\Samples\Comp Layer\TFDConnection\Pooling。

Subversion Repository:你可以在GitHub存储库中找到Delphi代码样本。根据你的RAD Studio版本,按名称搜索到样本库。

如果觉得《Delphi 中 FireDAC 数据库连接(多线程)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。