中间件--连接池

unit untDBPool;

{$I def.inc}
interface

uses
Classes, SyncObjs, SysUtils,
DateUtils, untDB, Windows, untGlobal;

type
TLoopThread=class(TThread)
private
CS: TCriticalSection;
protected
procedure Execute; override;
public
constructor Create; overload;
destructor Destroy; override;
end;

TDBPool = class
private
FCS: TCriticalSection;
FFreelist, FUsedList: TList;
FCount: integer;
FDatabaseParams: TDBParams;
public
constructor Create; overload;
destructor Destroy; override;
procedure Init;
function Lock: TfrmDB;
procedure Unlock(Value: TfrmDB);
function NewObj: TfrmDB;
property Count: integer read FCount default 0;
property DatabaseParams: TDBParams read FDatabaseParams
write FDatabaseParams;
end;

var
DBPool: TDBPool;
loopThread: TLoopThread;

implementation

uses untLog;

constructor TDBPool.Create;
begin
FFreelist := TList.Create;
FUsedList := TList.Create;
FCS := TCriticalSection.Create;
loopThread := TLoopThread.Create;
end;

destructor TDBPool.Destroy;
begin
while FFreelist.Count > 0 do
begin
TfrmDB(FFreelist[0]).con.Close;
TfrmDB(FFreelist[0]).Free;
FFreelist.Delete(0);
end;
while FUsedList.Count > 0 do
begin
TfrmDB(FFreelist[0]).con.Close;
TfrmDB(FUsedList[0]).Free;
FUsedList.Delete(0);
end;
FreeAndNil(FFreelist);
FreeAndNil(FUsedList);
FreeAndNil(FCS);
loopThread.Terminate;
loopThread.WaitFor;
FreeAndNil(loopThread);
inherited Destroy;
end;

procedure TDBPool.Init;
var
f: TfrmDB;
begin
while FFreelist.Count < poolParams.poolSize do
begin
f := NewObj;
if f <> nil then
begin
f.TimeStamp := GetTickCount;
f.ConnectDB;
FFreelist.Add(f);
end;
end;
end;

function TDBPool.Lock: TfrmDB;
begin
FCS.Enter;
try
if FFreelist.Count > 0 then
begin
Result := TfrmDB(FFreelist[0]);
if not Result.Connected then
Result.ConnectDB;
FFreelist.Delete(0);
FUsedList.Add(Result);
end
else
Result := nil;
if Result = nil then
begin
Result := NewObj;
if Result <> nil then
begin
Result.ConnectDB;
Result.Tag := 5;
end;
end;
finally
FCS.Leave;
end;
end;

function TDBPool.NewObj: TfrmDB;
begin
Result := nil;
if poolParams.maxValue = 0 then
begin
Result := TfrmDB.Create(nil);
Result.DatabaseParams := Self.DatabaseParams;
inc(FCount);
end
else if (poolParams.maxValue <> 0) and (FCount < poolParams.maxValue)
then
begin
Result := TfrmDB.Create(nil);
Result.DatabaseParams := Self.DatabaseParams;
inc(FCount);
end;
end;

procedure TDBPool.Unlock(Value: TfrmDB);
procedure _Free;
begin
Value.DisConnectDB;
FreeAndNil(Value);
Dec(FCount);
end;

begin
if Value = nil then
exit;
FCS.Enter;
try
if Value.Tag = 5 then
begin
_Free;
end
else
begin
if FFreelist.Count < poolParams.poolSize then
begin
FUsedList.Delete(FUsedList.IndexOf(Value));
FFreelist.Add(Value);
Value.TimeStamp:=GetTickCount;
end
else
_Free;
end;
finally
FCS.Leave;
end;
end;

{ TLoopThread }

constructor TLoopThread.Create;
begin
inherited Create(False);
Self.FreeOnTerminate := false;
CS := TCriticalSection.Create;
end;

destructor TLoopThread.Destroy;
begin
CS.Free;
inherited;
end;

procedure TLoopThread.Execute;
var
i: Integer;
begin
inherited;
while not Self.Terminated do
begin
Sleep(5*60*1000);
CS.Enter;
try
if not Assigned(DBPool) then Continue;
if DBPool.FFreelist.Count <=0 then Continue;
for i := DBPool.FFreelist.Count -1 downto 0 do
begin
if ((GetTickCount-TfrmDB(DBPool.FFreelist[i]).TimeStamp) div (60*1000))
>=Cardinal(poolParams.timeout) then
begin
TfrmDB(DBPool.FFreelist[i]).con.Close;
TfrmDB(DBPool.FFreelist[i]).Free;
DBPool.FFreelist.Delete(i);
end else Continue;
end;
finally
CS.Leave;
end;
end;

end;

end.

时间: 2025-01-01 08:58:08

中间件--连接池的相关文章

数据库会自动清除掉超时的空闲连接造成中间件连接池中连接断开的问题

所有的数据库都会自动清除掉超时的空闲连接,因为数据库本身是一个SOCKET服务器,它必须要定时清除掉僵死连接,来保持其长时间稳定运行. 数据库清除空闲连接以后,中间件连接池里面con.connected还是等于true,也就是说在中间件里面是无法判断连接池中的连接是否已经被数据库给清除了. 事实上中间件连接池中的所有连接必须保持24小时的连接是通的.那么如何解决这个矛盾呢? 答案是在连接池中设置定时器,定时检查池中的每一个连接,当池中的空闲连接已经超过了半小时,就自动将此连接断开并重连. {**

数据库死锁严重引发中间件连接池满故障诊断

1.故障现象 前台系统应用无法登陆,weblogic服务器应用程序的运行状态显示为overload,线程连接池满. 2.故障原因分析 根据上述故障现象,分析基础可以确定为是Weblogic有过多的连接连到数据库,因为会话一直保持未释放,将连接池占满后,导致新的连接无法请求到连接池.在此关键是分析为什么会有大量的会话占满连接池而不释放. 3.问题分析过程 3.1 session数超过1000 Snap Id Snap Time Sessions Cursors/Session Begin Snap

几个主流的Java连接池整理

池(Pool)技术在一定程度上可以明显优化服务器应用程序的性能,提高程序执行效率和降低系统资源开销.这里所说的池是一种广义上的池,比如数据库连接池.线程池.内存池.对象池等.其中,对象池可以看成保存对象的容器,在进程初始化时创建一定数量的对象.需要时直接从池中取出一个空闲对象,用完后并不直接释放掉对象,而是再放到对象池中以方便下一次对象请求可以直接复用.其他几种池的设计思想也是如此,池技术的优势是,可以消除对象创建所带来的延迟,从而提高系统的性能. 要了解Java连接池我们先要了解数据库连接池(

几个主流java连接池

池(Pool)技术在一定程度上可以明显优化服务器应用程序的性能,提高程序执行效率和降低系统资源开销.这里所说的池是一种广义上的池,比如数据库连接池.线程池.内存池.对象池等.其中,对象池可以看成保存对象的容器,在进程初始化时创建一定数量的对象.需要时直接从池中取出一个空闲对象,用完后并不直接释放掉对象,而是再放到对象池中以方便下一次对象请求可以直接复用.其他几种池的设计思想也是如此,池技术的优势是,可以消除对象创建所带来的延迟,从而提高系统的性能. 要了解Java连接池我们先要了解数据库连接池(

《java数据源—连接池》

<java数据源-连接池>1.数据源的分类:直接数据源.连接池数据源.2.连接池.数据源.JNDI a.数据源:Java中的数据源就是连接到数据库的一条路径,数据源中并无真正的数据,它仅仅记录的是你连接到哪个数据库,以及如何连接. b.连接池:简单的说就是保存所有的数据库连接的地方,在系统初始化时,将数据库连接对象存储到内存里,当用户需要访问数据库的时候,并不是建立一个新的连接,而是从连接池中 取出一个已经建立好的空闲连接对象.而连接池负责分配.管理.释放数据库连接对象.注意的是:连接池是由容

MySQL中间件之ProxySQL(5):线程、线程池、连接池

1.ProxySQL的线程 ProxySQL由多个模块组成,是一个多线程的daemon类程序.每个模块都有一个或多个线程去执行任务. 例如,以下是刚启动ProxySQL时的进程情况,一个main进程,一个主线程,21个线程. [[email protected] ~]# pstree | grep proxy |-proxysql---proxysql---21*[{proxysql}] 下面是正常运行时使用的线程列表: 1.1 Main thread 这其实是一个进程,该进程只负责引导.启动核

oracle database resident connection pooling(驻留连接池)

oracle在11g中引入了database resident connection pooling(DRCP).在此之前,我们可以使用dedicated 或者share 方式来链接数据库,dedicated方式是oracle数据库默认的链接方式,无需过多的配置,而且关于dedicated的bug也是非常少的,因此,通常情况下,建议使用dedicated方式来链接数据库.但是,在服务器资源有限,并且同时连接数据库的用户量非常大时,dedicated方式就无能为力了.假设并发用户为5000,每个d

php连接池 php–cp

原文地址:http://blog.sina.com.cn/s/blog_9eaa0f400102v9fd.html 数据库连接池php-cp介绍时间 2015-01-23 11:53:05 数据库连接池 php-cpphp-cp(php-connect-pool)是用php扩展写的一个数据库连接池. 我们知道php开发速度快,适合创业快速迭代,但当流量大了之后,php大量的短连接给db层造成多余的消耗,而php处理请求过程中连接会一直持有再加上进程之间不能共享tcp连接会导致撑高mysql的连接

ibatis配置连接池

iBatis的连接设置 持久层中间件iBatis连接数据库的方式有3种,连接数据库的方式是JDBC,可以通过在XML文件中配置数据库连接,也可以在properties文件中配置.下面列出transactionManager的type为JDBC的3种连接配置. dataSource的type为SIMPLE的连接配置 以下是配置数据库连接参数的properties文件sql-map-config.properties的内容: ## SimpleDataSource properties ## Use