创建 Delphi DataSnap 程序的问题集萃(3)

本文介绍了如何在 Delphi XE5 的 DataSnap 项目中实现服务器端数据库连接的共享,以避免大量数据库连接带来的问题。通过创建一个数据库连接列表,保存并管理每个客户端的连接,确保在客户端断开连接时正确释放资源。同时,建议开启数据库连接池以优化资源使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(本文所讨论的开发环境,为 Delphi XE5)
    本篇介绍如何实现服务器端数据库连接的共享。

    常见的数据库连接实现,是为每个数据模块建立一个连接。但这样做将产生大量的数据库连接,并产生很多问题。
    在上一篇,我们分析了 Datasnap 客户端连接服务器端时相关事件的执行顺序。其中,ServerContainerUnit1 容器是在服务器端一开始运行时就创建,直到服务器端关闭、停止服务时才结束。因此,我们可以在容器对象生成时,创建一个数据库连接列表,用于保存为每个客户端创建的数据库连接对象,该列表对象在容器销毁时销毁;并在容器中实现了一个获取数据库连接的方法。
    
    下面以 TADOConnection 为例,数据库连接列表 ConnectionList 的定义如下:
type
  TServerContainer1 = class(TDataModule)
  ......
  private
    { Private declarations }
    ConnectionList: TDictionary<Integer, TADOConnection>;
  public
    //获取数据库连接对象
    //参数:(如果不存在则新建) CreateNewIfNotExist
    function GetConnection(CreateNewIfNotExist: Boolean = True): TADOConnection;
    ......
    
    创建 ConnectionList 对象:
procedure TServerContainer1.DataModuleCreate(Sender: TObject);
begin
  ConnectionList := TDictionary<Integer, TADOConnection>.Create;
end;
    
    销毁 ConnectionList 对象:
procedure TServerContainer1.DataModuleDestroy(Sender: TObject);
begin
  ConnectionList.Free;
end;
    
    获取数据库连接的思路是:如果当前客户端的数据库连接已经存在,则直接从 ConnectionList 里取出;如果不存在,根据参数 CreateNewIfNotExist 判断是否创建;如果创建,则创建一个新连接,并将连接保存到 ConnectionList 中。ConnectionList 中的 Key 值为客户端连接时的线程ID。
    代码如下:
function TServerContainer1.GetConnection(CreateNewIfNotExist: Boolean): TADOConnection;
var
  dbConn: TADOConnection;
begin
  Result := nil;
  if ConnectionList.ContainsKey(TDSSessionManager.GetThreadSession.Id) then
  begin
    Result := ConnectionList[TDSSessionManager.GetThreadSession.Id];
  end
  else if CreateNewIfNotExist then
  begin
    dbConn := TADOConnection.Create(nil);
    dbConn.ConnectionString := csConnectionString;
    dbConn.LoginPrompt := False;

    ConnectionList.Add(TDSSessionManager.GetThreadSession.Id, dbConn);
    Result := dbConn;
  end;
end;
    
    当客户端断开连接时,要同时释放该客户端的数据库连接,以防止内存泄露。
procedure TServerContainer1.DSServer1Disconnect(DSConnectEventObject: TDSConnectEventObject);
var
  dbConn: TADOConnection;
begin
  if ConnectionList.ContainsKey(TDSSessionManager.GetThreadSession.Id) then
  begin  //如果实例存在
    dbConn := ConnectionList[TDSSessionManager.GetThreadSession.Id];
    ConnectionList.Remove(TDSSessionManager.GetThreadSession.Id);
    dbConn.Free;
  end;
end;
    
    为了防止客户端过多导致数据库连接被使用完毕造成错误,建议一定要开启数据库的连接池功能,以便让所有的客户端都分享数据库连接;而在编写服务方法时,请在执行前打开连接,在方法执行完毕后关闭连接(注意,是关闭连接,而不是释放数据库连接对象)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值