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

来源:互联网 发布:百度地图大数据报告 编辑:程序博客网 时间:2024/05/17 05:07
(本文所讨论的开发环境,为 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;        为了防止客户端过多导致数据库连接被使用完毕造成错误,建议一定要开启数据库的连接池功能,以便让所有的客户端都分享数据库连接;而在编写服务方法时,请在执行前打开连接,在方法执行完毕后关闭连接(注意,是关闭连接,而不是释放数据库连接对象)。
0 0
原创粉丝点击