传统的应用服务器的开发往往是在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.

版权声明:本文为博主原创文章,未经博主允许不得转载。

DataSnap数据库连接池,数据集对象池的应用的更多相关文章

  1. paip.提升性能----数据库连接池以及线程池以及对象池

    paip.提升性能----数据库连接池以及线程池以及对象池 目录:数据库连接池c3po,线程池ExecutorService:Jakartacommons-pool对象池 作者Attilax  艾龙, ...

  2. 传统对象池&AB对象池

    前序: Q:为啥需要对象池? A: 游戏中大量出现或销毁对象时会反复的开堆和放堆,程序与内存之间交互过于频繁导致资源的大量浪费 Q: 对象池实现原理? A: 当子对象池没有物体的时候,它会和普通没加对 ...

  3. 论DATASNAP中间件对象池

    在此,笔者以DATASNAP为例,其它中间件以此类推. 中间件为什么要使用对象池? 对象池——让所有的对象免堕轮回之苦,对象不再为其生和死而烦恼. 要想让中间件长久稳定地运行,做到无人值守,对象池很重 ...

  4. Apache Common-pool2对象池分析和应用

    Apache Common-pool2包提供了一个通用的对象池技术的实现.可以很方便的基于它来实现自己的对象池,比如DBCP和Jedis他们的内部对象池的实现就是依赖于Common-pool2. 对象 ...

  5. java对象池commons-pool-1.6详解(一)

    自己的项目中用到了 对象池 commons-pool: package com.sankuai.qcs.regulation.protocol.client; import com.dianping. ...

  6. Java对象池技术的原理及其实现

    看到一片有关于java 对象基础知识,故转载一下,同时学习一下. 摘 要 本文在分析对象池技术基本原理的基础上,给出了对象池技术的两种实现方式.还指出了使用对象池技术时所应注意的问题. 关键词 对象池 ...

  7. Java网络与多线程系列之1:实现一个简单的对象池

    前言 为什么要从对象池开始呢,先从一个网络IO操作的demo说起 比如下面这段代码,显而易见已经在代码中使用了一个固定大小的线程池,所以现在的重点在实现Runnble接口的匿名对象上,这个对象每次创建 ...

  8. 对象池与.net—从一个内存池实现说起

    本来想写篇关于System.Collections.Immutable中提供的ImmutableList里一些实现细节来着,结果一时想不起来源码在哪里--为什么会变成这样呢--第一次有了想写分析的源码 ...

  9. Unity 游戏框架搭建 (十九) 简易对象池

    在Unity中我们经常会用到对象池,使用对象池无非就是解决两个问题: 一是减少new时候寻址造成的消耗,该消耗的原因是内存碎片. 二是减少Object.Instantiate时内部进行序列化和反序列化 ...

随机推荐

  1. Amazon Launches FBA Export to Expand Beyond Media Categories

    Amazon launched a new program called FBA Export for third-party sellers to help them export products ...

  2. java根据图片和文字生成自定义图片

    import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; i ...

  3. C#生成DBF文件

    C# 生成DBF,无需注册Microsoft.Jet.OLEDB. namespace ConsoleApplication { class Program { static void Main(st ...

  4. c#几个小例子引发的思考

    楚广明老师的c#教程每一节都会给出几个小例子让大家联系,对于初学者来说这确实是一件很纠结的事情,下面我把这几个小例子简单的写一下.同时看一下我们学到了什么 1.面向过程版的圆周长面积计算 using ...

  5. HDU 1069 Monkey and Banana (DP)

    Monkey and Banana Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  6. Convert.ToInt32( null or "")

    由于总忘记,先写一下. Console.WriteLine("输出转换空结果 ={0}", Convert.ToInt32("")); //Convert.To ...

  7. 表数据转换为insert语句

    /* 对象:导出物理表数据为Insert语句 描述:可以传递条件精确导出sql 加条件的前提是只知道相应的字段名及类型 */ from sysobjects where name ='proc_ins ...

  8. Bootstrap 小技巧以及相关资源整理

    1, Bootstrap Bundle (http://bootstrapbundle.com/): 提供了15中不同的MVC  Bootstrap模板.[扩展和更新]中搜索“Bootstrap Bu ...

  9. C# 线程抛异常

    异常抛出 异常抛出要在线程代码中抛出,否则捕获不到 using System; using System.Threading; namespace testthread_keyword_lock { ...

  10. Android之adb命令

    1.安装APK(如果加 -r 参数,保留已设定数据,重新安装filename.apk) adb install xxx.apk adb install -r xxx.apk 2.卸载APK(如果加 - ...