传统的应用服务器的开发往往是在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.
版权声明:本文为博主原创文章,未经博主允许不得转载。