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


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

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

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

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

    unit DSServerContainer;
    
    interface
    
    uses
      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;
    
    implementation
    
    uses 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;
    
    interface
    
    uses
      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.

  • 相关阅读:
    TP之Model(select(),add())
    TP之空操作及View模块
    ThinkPHP之初识
    smarty引擎之练习
    领先环境HTML
    php流程
    分页
    弹窗
    邮箱项目
    TP框架修改操作
  • 原文地址:https://www.cnblogs.com/xieyunc/p/9126535.html
Copyright © 2020-2023  润新知