ADOConnection数据库连接池
unit AdoconnectPool;
interface
uses
Classes, Windows, SysUtils, ADODB, IniFiles, forms;
type
TADOConnectionPool = class(TObject)
private
FObjList:TThreadList;
FTimeout: Integer;
FMaxCount: Integer;
FSemaphore: Cardinal;
function CreateNewInstance(List:TList): TADOConnection;
function GetLock(List:TList;Index: Integer): Boolean;
public
property Timeout:Integer read FTimeout write FTimeout;
property MaxCount:Integer read FMaxCount;
constructor Create(ACapicity:Integer=30);overload;
destructor Destroy;override;
function Lock: TADOConnection;
procedure Unlock(var Value: TADOConnection);
end;
var
ConnPool: TADOConnectionPool;
g_ini: TIniFile;
implementation
constructor TADOConnectionPool.Create(ACapicity:Integer=30);
begin
FObjList:=TThreadList.Create;
FTimeout := 3000; // 3 second
FMaxCount := ACapicity;
FSemaphore := CreateSemaphore(nil, FMaxCount, FMaxCount, nil);
end;
function TADOConnectionPool.CreateNewInstance(List:TList): TADOConnection;
var
p: TADOConnection;
function GetConnStr: string;
begin
try
Result := g_ini.ReadString('ado','connstr','');
except
Exit;
end;
end;
begin
try
p := TADOConnection.Create(nil);
p.ConnectionString := GetConnStr;
p.LoginPrompt := False;
p.Connected:=True;
p.Tag := 1;
List.Add(p);
Result := p;
except
on E: Exception do
begin
Result := nil;
Exit;
end;
end;
end;
destructor TADOConnectionPool.Destroy;
var
i: Integer;
List:TList;
begin
List:=FObjList.LockList;
try
for i := List.Count - 1 downto 0 do
begin
TADOConnection(List[i]).Free;
end;
finally
FObjList.UnlockList;
end;
FObjList.Free;
FObjList := nil;
CloseHandle(FSemaphore);
inherited;
end;
function TADOConnectionPool.GetLock(List:TList;Index: Integer): Boolean;
begin
try
Result := TADOConnection(List[Index]).Tag = 0;
if Result then
TADOConnection(List[Index]).Tag := 1;
except
Result :=False;
Exit;
end;
end;
function TADOConnectionPool.Lock: TADOConnection;
var
i: Integer;
List:TList;
begin
try
Result :=nil;
if WaitForSingleObject(FSemaphore, Timeout) = WAIT_FAILED then Exit;
List:=FObjList.LockList;
try
for i := 0 to List.Count - 1 do
begin
if GetLock(List,i) then
begin
Result := TADOConnection(List[i]);
PostMessage(Application.MainForm.Handle,8888,13,0);
Exit;
end;
end;
if List.Count < MaxCount then
begin
Result := CreateNewInstance(List);
PostMessage(Application.MainForm.Handle,8888,11,0);
end;
finally
FObjList.UnlockList;
end;
except
Result := nil;
Exit;
end;
end;
procedure TADOConnectionPool.Unlock(var Value: TADOConnection);
var
List:TList;
begin
try
List:=FObjList.LockList;
try
TADOConnection(List[List.IndexOf(Value)]).Tag :=0;
ReleaseSemaphore(FSemaphore, 1, nil);
finally
FObjList.UnlockList;
end;
PostMessage(Application.MainForm.Handle, 8888, 12, 0);
except
Exit;
end;
end;
initialization
ConnPool := TADOConnectionPool.Create();
g_ini := TIniFile.Create(ExtractFilePath(Application.ExeName)+'server.ini');
finalization
FreeAndNil(ConnPool);
FreeAndNil(g_ini);
end.
本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/archive/2012/01/11/2319952.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?