DataSnap数据库连接池,数据集对象池的应用

来源:互联网 发布:seo分析师 编辑:程序博客网 时间:2024/04/29 10:27

    传统的应用服务器的开发往往是在ServerMethods单元中拖放一堆TDataSet, TDaTaSetProvider控件,这是一个最简单粗暴的开发方向,往往会造成服务端程序文件的臃肿、服务运行期间内存资源消耗过大的问题。因此这种往应用服务器中拖放一堆TDataSet, TDaTaSetProvider控件的做法,非常的笨拙。

    当然了,如果我们的系统采用的是以短连接的方式的话,那就可以每次直接TDataSet.Create(nil);然后Free;但是这种方法对服务器的开销很大,因为每执行一个服务都需要重复开辟内存空间,销毁内存空间等。

    为此,我们可以通过使用对象池方法来改进之。

一、数据库连接池:TConnection对象池

unit DSServerContainer;interfaceuses  SysUtils, Classes,  DSTCPServerTransport,  DSServer, DSCommonServer, DSAuth, DB, ADODB, Generics.Collections, DSService,  DBXDataSnap, DBXCommon, DSHTTPLayer, DBXinterbase, Forms;type  TServerContainer1 = class(TDataModule)    DSServer1: TDSServer;    DSTCPServerTransport1: TDSTCPServerTransport;    DSServerClass1: TDSServerClass;    procedure DSServerClass1GetClass(DSServerClass: TDSServerClass;      var PersistentClass: TPersistentClass);    procedure DataModuleCreate(Sender: TObject);    procedure DSServer1Disconnect(DSConnectEventObject: TDSConnectEventObject);  private    { Private declarations }    ListofConnection : TDictionary<Integer,TadoConnection>;  public    function getConnection : TAdoConnection;  end;var  ServerContainer1: TServerContainer1;implementationuses Windows, ServerMethodsUnit1,uConst;{$R *.dfm}procedure TServerContainer1.DataModuleCreate(Sender: TObject);begin  ListofConnection := TDictionary<Integer, TadoConnection>.Create;end;procedure TServerContainer1.DSServer1Disconnect(  DSConnectEventObject: TDSConnectEventObject);begin  if getConnection <> nil then     getConnection.Close;end;procedure TServerContainer1.DSServerClass1GetClass(  DSServerClass: TDSServerClass; var PersistentClass: TPersistentClass);begin  PersistentClass := ServerMethodsUnit1.TServerMethods1;end;function TServerContainer1.getConnection: TAdoConnection;var  dbconn : TAdoConnection;begin  if ListofConnection.ContainsKey(TDSSessionManager.GetThreadSession.Id) then     Result := ListofConnection[TDSSessionManager.GetThreadSession.Id]  else  begin    if ListofConnection.Count <= g_MaxPoolSize then    begin      dbconn := TadoConnection.Create(Self);      dbconn.Name := 'con'+ IntToStr(TDSSessionManager.GetThreadSession.Id);      dbconn.LoginPrompt := false;      dbconn.ConnectionString := 'FILE NAME=' + extractfilepath(application.ExeName) + 'connect.udl';      ListofConnection.Add(TDSSessionManager.GetThreadSession.Id, dbconn);      Result := dbconn;    end;  end;end;end.
二、数据集对象池:TDataSet和TDataSetProvider的池化

unit ServerMethodsUnit1;interfaceuses  SysUtils, Classes, DSServer, DB, Generics.Collections, DSService, Provider,  ADODB;type  TServerMethods1 = class(TDSServerModule)    procedure DSServerModuleCreate(Sender: TObject);  private    { Private declarations }    ListofQuery : TDictionary<Integer,TAdoQuery>;    ListofProvider : TDictionary<Integer,TDatasetProvider>;    function _GetQuery(sql: string; exeNo: Integer) : TAdoquery;    function _GetPrv(sql: string; exeNo: Integer) : TDatasetProvider;  public    { Public declarations }    function GetProviderName(sql: string; exeNo: Integer): string;  end;implementation{$R *.dfm}uses StrUtils, DSServerContainer, uConst;procedure TServerMethods1.DSServerModuleCreate(Sender: TObject);begin  Listofquery := TDictionary<Integer, Tadoquery>.Create;  Listofprovider := TDictionary<Integer, Tdatasetprovider>.Create;end;function TServerMethods1._GetPrv(sql: string; exeNo: Integer): TDatasetProvider;var  dbprv : Tdatasetprovider;begin  if ListofProvider.ContainsKey(exeNo) then     Result := ListofProvider[exeNo]  else  begin    if ListofProvider.Count <= g_MaxPoolSize then    begin      dbprv := TDataSetProvider.Create(Self);      dbprv.Name := 'dsp'+ IntToStr(exeNo);      dbprv.DataSet := _GetQuery(sql, exeNo);      ListofProvider.Add(exeNo, dbprv);      Result := dbprv;    end;  end;end;function TServerMethods1._GetQuery(sql: string; exeNo: Integer): TAdoQuery;var  qry : TADOQuery;begin  if Listofquery.ContainsKey(exeNo) then     Result := ListofQuery[exeNo]  else  begin    if ListofQuery.Count <= g_MaxPoolSize then    begin      qry := TADOQuery.Create(Self);      with qry do      begin        Connection := ServerContainer1.getConnection;        Name := 'qry'+ IntToStr(exeNo);        close;        sql.Clear;        sql.Text := sql;        open;      end;      ListofQuery.Add(exeNo, qry);      Result := qry;    end;  end;end;function TServerMethods1.GetProviderName(sql: string; exeNo: Integer): string;begin  Result := _GetPrv(sql, exeNo).Name;end;end.

0 0
原创粉丝点击