关于连接池(Connection Pool)的问题. ( 积分: 300 )

  • 主题发起人 主题发起人 gear1023
  • 开始时间 开始时间
G

gear1023

Unregistered / Unconfirmed
GUEST, unregistred user!
现有一旧的三层系统.
中间层定义为 MultiInstance + Single + 单Connection 模式.

用户一多效率太差,修改其中间层方式 MultiInstance + Apartment + 多个Connection ;
放一List保存所有的Connection,在有客户连接时从列表中挑出一个Connection(按时间先后).
[red]问题[/red]: [brown]当同一Connection的两个用户同时操作时,会出现错误[/brown].
[blue]想法[/blue]: 当Connection无法使用(如Connection忙),可以修改到其它 Connection.
请问如何实现或何时实现 或其它解决方法.
 
现有一旧的三层系统.
中间层定义为 MultiInstance + Single + 单Connection 模式.

用户一多效率太差,修改其中间层方式 MultiInstance + Apartment + 多个Connection ;
放一List保存所有的Connection,在有客户连接时从列表中挑出一个Connection(按时间先后).
[red]问题[/red]: [brown]当同一Connection的两个用户同时操作时,会出现错误[/brown].
[blue]想法[/blue]: 当Connection无法使用(如Connection忙),可以修改到其它 Connection.
请问如何实现或何时实现 或其它解决方法.
 
在delphi的帮助中输入 RegisterPooled,里面有例子
class procedure TMyRDM.UpdateRegistry(Register: Boolean;
const ClassID, ProgID: string);
begin
if Register then
begin
inherited UpdateRegistry(Register, ClassID, ProgID);
{ EnableSocketTransport(ClassID);
}
EnableWebTransport(ClassID);
RegisterPooled(ClassID, 16, 30);
end else
begin
{ DisableSocketTransport(ClassID);
}
DisableWebTransport(ClassID);
UnregisterPooled(ClassID);
inherited UpdateRegistry(Register, ClassID, ProgID);
end;

end;
 
我有一线程池的代码,送给你看看吧。是一老外写的。
////////////////////////////////////////////////////////////////////////////////
//
// The uADOConnectionPool unit contains ADOConnectionPool classes.
//
unit uADOConnectionPool;
interface
uses
Classes, DB, uConnectionPool, ADODB;
type
//////////////////////////////////////////////////////////////////////////////
//
// Summary:
// TADOPoolConnection represents a connection in a ADO connection pool
// (TADOConnectionPool).
//
// Description:
// Each TADOConnectionPool uses a TPoolConnections to maintain a
// collection of TADOPoolConnection objects. Each TADOPoolConnection object
// represents the single database connection (TADOConnection) in the pool.
//
TADOPoolConnection = class(TPoolConnection)
protected
procedure Lock;
override;
procedure Unlock;
override;
function CreateConnection: TCustomConnection;
override;
end;

//////////////////////////////////////////////////////////////////////////////
//
// Summary:
// TADOConnectionPool is a connection pool realisation for ADO.
//
// SeeAlso:
// TCustomConnectionPool, TADOConnection
//
TADOConnectionPool = class(TCustomConnectionPool)
private
FCommandTimeout: Integer;
FConnectionTimeout: Integer;
FDefaultDatabase: String;
FConnectionString: WideString;
FMode: TConnectMode;
FConnectOptions: TConnectOption;
FCursorLocation: TCursorLocation;
FIsolationLevel: TIsolationLevel;
FAttributes: TXactAttributes;
protected
function GetPoolItemClass: TPoolConnectionClass;
override;
public
constructor Create(aOwner: TComponent);
override;
procedure Assign(Source: TPersistent);
override;
procedure AssignTo(Dest: TPersistent);
override;
published
//
// Summary:
// Specifies automated transaction behavior.
//
// Description:
// Set Attributes to specify whether a connection object performs
// retaining commits or retaining aborts. The two behaviors are
// independent of each other.
//
// Attributes can contain one of the two TXactAttribute values
// (xaCommitRetaining and xaAbortRetaining), both values, or neither
// value.
//
// SeeAlso:
// TADOConnection.Attributes
//
property Attributes: TXactAttributes read FAttributes write FAttributes;
//
// Summary:
// Specifies the connection information for the data store.
//
// Description:
// Set ConnectionString to specify the information needed to connect the
// ADO connection component to the data store. The value used for
// ConnectionString consists of one or more arguments ADO uses to
// establish the connection. Specify multiple arguments as a list with
// individual arguments separated by semicolons.
//
// SeeAlso:
// TADOConnection.ConnectionString
//
property ConnectionString: WideString read FConnectionString write FConnectionString;
//
// Summary:
// Specifies amount of time to attempt execution of a command.
//
// Description:
// Use CommandTimeout to specify the amount of time, in seconds, that that
// can expire before an attempt to execute a command is considered
// unsuccessful. The default value is 30 seconds.
//
// SeeAlso:
// TADOConnection.CommandTimeout
//
property CommandTimeout: Integer read FCommandTimeout write FCommandTimeout default 30;
//
// Summary:
// Specifies amount of time to attempt a connection.
//
// Description:
// Use ConnectionTimeout to specify the amount of time, in seconds, that
// can expire before an attempt to make a connection is considered
// unsuccessful. The default value is 15 seconds.
//
// If a connection is successfully made prior to the expiration of the
// seconds specified or the Cancel method is called, ConnectionTimeout has
// no effect. If the specified time expires and a connection has not been
// successfully made, the attempt is terminated and an exception is
// raised.
//
// SeeAlso:
// TADOConnection.ConnectionTimeout
//
property ConnectionTimeout: Integer read FConnectionTimeout write FConnectionTimeout default 15;
//
// Summary:
// Specifies whether a connection is synchronous or asynchronous.
//
// Description:
// Set ConnectOptions to specify whether the connection established by the
// TADOConnection is synchronous or asynchronous. The default value for
// ConnectOptions is coConnectUnspecified.
//
// An application will typically use the default of a synchronous
// connection (coConnectUnspecified). Typically an asynchronous is only
// really needed to compensate for a slow server.
//
// SeeAlso:
// TADOConnection.ConnectOptions
//
property ConnectOptions: TConnectOption read FConnectOptions write FConnectOptions default coConnectUnspecified;
//
// Summary:
// Specifies whether cursors for the connection is client-side or
// server-side.
//
// Description:
// Use CursorLocation to indicate whether the cursors that use the
// connection object to connect to the ADO datastore use a client-side or
// server-side cursor library. CursorLocation only affects connections
// opened after the property is set. The default value for
// CursorLocation is clUseClient.
//
// SeeAlso:
// TADOConnection.CursorLocation
//
property CursorLocation: TCursorLocation read FCursorLocation write FCursorLocation default clUseClient;
//
// Summary:
// Indicates the database the ADO connection uses by default.
//
// Description:
// Set DefaultDatabase to indicate the database the ADO connection objects
// uses if the connection to the database specified in ConnectionString is
// unavailable, the connection cannot be made, or the database is not
// specified in the connection string.
//
// SeeAlso:
// TADOConnection.DefaultDatabase
//
property DefaultDatabase: String read FDefaultDatabase write FDefaultDatabase;
//
// Summary:
// Specifies the transaction isolation level for transactions.
//
// Description:
// Use IsolationLevel to specify the transaction isolation level for a
// connection. The transaction isolation level determines how a
// transaction interacts with other simultaneous transactions when they
// work with the same tables, and how much a transaction sees of the work
// performed by other transactions. The default value for IsolationLevel
// is ilCursorStability.
//
// SeeAlso:
// TADOConnection.IsolationLevel
//
property IsolationLevel: TIsolationLevel read FIsolationLevel write FIsolationLevel default ilCursorStability;
//
// Summary:
// Indicate the persimissions available to a connection.
//
// Description:
// Read Mode to determine the permissions available to the connection
// after the connection has been activated. The permissions expressed in
// Mode govern the types of operations (such as reading and writing) can
// be performed through the connection. They also control how these
// operations are affected by and affect other concurrent users.
//
// SeeAlso:
// TADOConnection.Mode
//
property Mode: TConnectMode read FMode write FMode default cmUnknown;
property MaxConnections;
property OnLockConnection;
property OnUnlockConnection;
property OnCreateConnection;
property OnLockFail;
property OnFreeConnection;

end;

implementation
uses
SysUtils;
{ TADOConnectionPoolItem }
{- protected ------------------------------------------------------------------}
function TADOPoolConnection.CreateConnection: TCustomConnection;
begin
Result:= TADOConnection.Create(nil);
with Result as TADOConnectiondo
begin
LoginPrompt:= false;
ConnectionString:= TADOConnectionPool(TPoolConnections(Collection).Owner).ConnectionString;
CommandTimeout:= TADOConnectionPool(TPoolConnections(Collection).Owner).FCommandTimeout;
ConnectionTimeout:= TADOConnectionPool(TPoolConnections(Collection).Owner).ConnectionTimeout;
ConnectOptions:= TADOConnectionPool(TPoolConnections(Collection).Owner).ConnectOptions;
CursorLocation:= TADOConnectionPool(TPoolConnections(Collection).Owner).CursorLocation;
DefaultDatabase:= TADOConnectionPool(TPoolConnections(Collection).Owner).DefaultDatabase;
IsolationLevel:= TADOConnectionPool(TPoolConnections(Collection).Owner).IsolationLevel;
Mode:= TADOConnectionPool(TPoolConnections(Collection).Owner).Mode;
end;
end;

procedure TADOPoolConnection.Lock;
begin
inherited;
(Connection as TADOConnection).begin
Trans;
end;

procedure TADOPoolConnection.Unlock;
begin
inherited;
if (Connection as TADOConnection).InTransaction then
try
(Connection as TADOConnection).CommitTrans;
except
(Connection as TADOConnection).RollbackTrans;
end;
end;

{ TADOConnectionPool }
{- protected ------------------------------------------------------------------}
function TADOConnectionPool.GetPoolItemClass: TPoolConnectionClass;
begin
Result:= TADOPoolConnection;
end;

{- public ---------------------------------------------------------------------}
constructor TADOConnectionPool.Create(aOwner: TComponent);
begin
inherited Create(aOwner);
FConnectionString:= '';
FCommandTimeout:= 30;
FConnectionTimeout:= 15;
FConnectOptions:= coConnectUnspecified;
FCursorLocation:= clUseClient;
FDefaultDatabase:= '';
FIsolationLevel:= ilCursorStability;
FMode:= cmUnknown;
end;

procedure TADOConnectionPool.Assign(Source: TPersistent);
begin
if Source is TADOConnection then
begin
ConnectionString:= TADOConnection(Source).ConnectionString;
CommandTimeout:= TADOConnection(Source).CommandTimeout;
ConnectionTimeout:= TADOConnection(Source).ConnectionTimeout;
ConnectOptions:= TADOConnection(Source).ConnectOptions;
CursorLocation:= TADOConnection(Source).CursorLocation;
DefaultDatabase:= TADOConnection(Source).DefaultDatabase;
IsolationLevel:= TADOConnection(Source).IsolationLevel;
Mode:= TADOConnection(Source).Mode;
end
else
inherited;
end;

procedure TADOConnectionPool.AssignTo(Dest: TPersistent);
begin
if Dest is TADOConnectionPool then
begin
TCustomConnectionPool(Dest).MaxConnections:= MaxConnections;
TADOConnectionPool(Dest).ConnectionString:= ConnectionString;
TADOConnectionPool(Dest).CommandTimeout:= CommandTimeout;
TADOConnectionPool(Dest).ConnectionTimeout:= ConnectionTimeout;
TADOConnectionPool(Dest).ConnectOptions:= ConnectOptions;
TADOConnectionPool(Dest).CursorLocation:= CursorLocation;
TADOConnectionPool(Dest).DefaultDatabase:= DefaultDatabase;
TADOConnectionPool(Dest).IsolationLevel:= IsolationLevel;
TADOConnectionPool(Dest).Mode:= Mode;
end
else
if Dest is TADOConnection then
begin
TADOConnection(Dest).ConnectionString:= ConnectionString;
TADOConnection(Dest).CommandTimeout:= CommandTimeout;
TADOConnection(Dest).ConnectionTimeout:= ConnectionTimeout;
TADOConnection(Dest).ConnectOptions:= ConnectOptions;
TADOConnection(Dest).CursorLocation:= CursorLocation;
TADOConnection(Dest).DefaultDatabase:= DefaultDatabase;
TADOConnection(Dest).IsolationLevel:= IsolationLevel;
TADOConnection(Dest).Mode:= Mode;
end
else
inherited;
end;

end.
 
////////////////////////////////////////////////////////////////////////////////
//
// The uConnectionPool unit contains base classes of Connection Pool.
//
unit uConnectionPool;
interface
uses
Classes, DB, SyncObjs, SysUtils;
type
TPoolConnectionClass = class of TPoolConnection;
TCustomConnectionPool = class;

//////////////////////////////////////////////////////////////////////////////
//
// Summary:
// TPoolConnection represents a connection in a connection pool
// (TCustomConnectionPool).
//
// Description:
// Each TCustomConnectionPool uses a TPoolConnections to maintain a
// collection of TPoolConnection objects. Each TPoolConnection object
// represents the single database connection in the pool.
//
TPoolConnection = class(TCollectionItem)
private
FBusy: Boolean;
FConnection: TCustomConnection;
protected
//
// Summary:
// Locks the connection in the connection pool
//
// Description:
// Lock mark connection as "locked"
and opens connection if it closed.
//
// SeeAlso:
// Busy, TCustomConnectionPool.GetConnection
//
procedure Lock;
virtual;
//
// Summary:
// Unlocks the connection in the connection pool
//
// Description:
// Unlock mark connection as "unlocked". Unlocked connection can be
// retreived by calling TCustomConnectionPool.GetConnection
//
// SeeAlso:
// Busy, TCustomConnectionPool.FreeConnection
//
procedure Unlock;
virtual;
//
// Summary:
// Connected checks database connection
//
// Result:
// True - if connection connected to database
// False - otherwise
//
// SeeAlso:
// Connection
//
function Connected: Boolean;
virtual;
//
// Summary:
// CreateConnection creates connection element
//
// Result:
// Newly created TCustomConnection descendant
//
// SeeAlso:
// Connection
//
function CreateConnection: TCustomConnection;
virtual;
abstract;
public
//
// Summary:
// Indicates that the connection has been locked.
//
// Description:
// Busy is a Boolean property that indicates when the connection has been
// locked.
//
// SeeAlso:
// Lock, Unlock
//
property Busy: Boolean read FBusy;
//
// Summary:
// Contains TCustomConnection descendants represented by this connection
// pool item.
//
// SeeAlso:
// TCustomConnectionPool.GetConnection,
// TCustomConnectionPool.FreeConnection
//
property Connection: TCustomConnection read FConnection;
//
// Summary:
// Creates and initializes a TPoolConnection instance.
//
// Description:
// The Create method takes as a parameter the name of a TCollection
// instance. Create is called by TPoolConnection抯 Add method.
//
// SeeAlso:
// TPoolConnections.Add
//
constructor Create(aCollection: TCollection);
override;
//
// Summary:
// Destroys the TPoolConnection instance and frees its memory.
//
// Description:
// Destroy is called indirectly by TCollection抯 Clear method.
//
// SeeAlso:
// TCollection.Clear
//
destructor Destroy;
override;
end;

//////////////////////////////////////////////////////////////////////////////
//
// Summary:
// TPoolConnections is a container for TPoolConnection objects.
//
// Description:
// Each TPoolConnections holds a collection of TPoolConnection objects in a
// connection pool (TCustomConnectionPool). TPoolConnections maintains an
// index of the connection in its Items array. The Count property contains
// the number of connections in the collection.
//
// SeeAlso:
// TCustomConnectionPool, TPoolConnection
//
TPoolConnections = class(TOwnedCollection)
private
function GetItem(aIndex: Integer): TPoolConnection;
procedure SetItem(aIndex: Integer;
const Value: TPoolConnection);
public
//
// Summary:
// Provides indexed access to the items in the collection.
//
// Description:
// Use Items to access individual items in the collection. The value of
// the Index parameter corresponds to the Index property of
// TPoolConnection. It represents the position of the item in the
// collection.
//
property Items[aIndex: LongInt]: TPoolConnection read GetItem write SetItem;
default;
//
// Summary:
// Creates a new TPoolConnection instance and adds it to the Items array.
//
// Description:
// Call Add to create an item in the collection. The new item is placed at
// the end of the Items array.
//
// Result:
// Add returns the new collection item.
//
function Add: TPoolConnection;
{$IFNDEF VER140}
//
// Summary:
// Returns the Owner of the collection.
//
// Description:
// Call Owner to obtain a reference to the object that owns this
// collection. Typically, the owner uses the collection to implement one
// of its properties.
//
function Owner: TPersistent;
{$ENDIF}
end;

TExceptionEvent = procedure (Sender: TObject;
E: Exception) of object;
//////////////////////////////////////////////////////////////////////////////
//
// Summary:
// TCustomConnection is the base class for components that represents a pool
// of connections to one database.
//
// Description:
// Use TCustomConnection as a base class for components that represent a
// poolof connections to one database.do
not create instances of
// TCustomConnectionPool. To add a component that represents the connection
// pool, use a TCustomConnectionPool descendant such as TBDEConnectioPool,
// TADOConnectionPool, TDBXConnectionPool.
//
// SeeAlso:
// TBDEConnectioPool, TADOConnectionPool, TDBXConnectionPool.
//
TCustomConnectionPool = class(TComponent)
private
FCS: TCriticalSection;
FConnections: TPoolConnections;
FMaxConnections: LongInt;
FOnLockConnection: TNotifyEvent;
FOnLockFail: TExceptionEvent;
FOnUnLockConnection: TNotifyEvent;
FOnCreateConnection: TNotifyEvent;
FOnFreeConnection: TNotifyEvent;
function GetUnusedConnections: LongInt;
function GetTotalConnections: LongInt;
protected
//
// Summary:
// Returns class of items into pool collection.
//
// Description:
// TCustomConnectionPool descendants overrides GetPoolItemClass for
// declaring class of items in the pool collection.
//
// Result:
// Class of items into pool collection.
//
function GetPoolItemClass: TPoolConnectionClass;
virtual;
abstract;
//
// Summary:
// Generates an OnLock event.
//
// Description:
// do
Lock is called automatically when connection locked. Override this
// method to provide additional processing other than calling the OnLock
// event handler.
//
// SeeAlso:
// OnLock, TPoolConnection.Lock
//
proceduredo
Lock;
virtual;
//
// Summary:
// Generates an OnLockFail event.
//
// Description:
// do
LockFail is called automatically when connection locking
// failed (Connection limit exceeded or any other error raised).
// Override this method to provide additional processing other than
// calling the OnLockFail event handler.
//
// SeeAlso:
// OnLockConnection, OnLockFail
//
proceduredo
LockFail(E: Exception);
virtual;
//
// Summary:
// Generates an OnUnlock event.
//
// Description:
// do
Unlock is called automatically when connection unlocked. Override
// this method to provide additional processing other than calling the
// OnUnlock event handler.
//
// SeeAlso:
// OnUnlock, TPoolConnection.Unlock
//
proceduredo
Unlock;
virtual;
//
// Summary:
// Generates an OnCreateConnection event.
//
// Description:
// do
CreateConnection is called automatically when new connection
// allocated. Override this method to provide additional processing other
// than calling the OnCreateConnection event handler.
//
// SeeAlso:
// OnCreateConnection
//
proceduredo
CreateConnection;
virtual;
//
// Summary:
// Generates an OnFreeConnection event.
//
// Description:
// OnFreeConnection is called automatically when connection destroyed
// Override this method to provide additional processing other than
// calling the OnCreateConnection event handler.
//
// SeeAlso:
// OnFreeConnection
//
proceduredo
FreeConnection;
virtual;
public
constructor Create(aOwner: TComponent);
override;
destructor Destroy;
override;
// Summary:
// Copies the contents of another ConnectionPool or Connection.
//
// Description:
// Call Assign to copy the properties of Connection Pool from another
// ConnectionPool or Connection. The standard form of a call to Assign is
// <CODE>
// Destination.Assign(Source);
// </CODE>
procedure AssignTo(Dest: TPersistent);
override;
//
// Summary:
// MaxConnections reprsents the max. number of connections in the pool.
//
// Description
// MaxConnections property is used to set the number of concurrent
// connections the connection pool will make to the database.
// If MaxConnections = -1, then
number of connections is unlimited.
//
// SeeAlso:
// GetConnection
//
property MaxConnections: LongInt read FMaxConnections write FMaxConnections default -1;
//
// Summary:
// Retreives connection from the pool.
//
// Description:
// GetConnection looks into connections list for unlocked connection.
// If none found and number of connections less than MaxConnections, then
// new connection is allocated.
//
// Result:
// Returns pooled connection.
//
// SeeAlso:
// FreeConnection, MaxConnections.
//
function GetConnection: TCustomConnection;
//
// Summary:
// Returns connection into the pool.
//
// Description:
// FreeConnection calls Unlock method of the TPoolConnection
//
// Parameters:
// aConnection - freed connection.
//
// SeeAlso:
// GetConnection
//
procedure FreeConnection(aConnection: TCustomConnection);
//
// Summary:
// Returns number of unused connections in the pool.
//
// Description:
// Use UnusedConnections for calculating number of allocated and not used
// connections.
//
property UnusedConnections: LongInt read GetUnusedConnections;
//
// Summary:
// Returns number of allocated connections in the pool.
//
// Description:
// Use TotalConnections for retrieving number of allocated connections in
// the pool.
//
property TotalConnections: LongInt read GetTotalConnections;
//
// Summary:
// Occurs when a connection into pool is locked.
//
// Description:
// Write an OnLockConnection event handler to take application-specific
// actions immediately after the connection pool component locks a
// connection.
//
property OnLockConnection: TNotifyEvent read FOnLockConnection write FOnLockConnection;
//
// Summary:
// Occurs when a connection into pool is unlocked.
//
// Description:
// Write an OnUnlockConnection event handler to take application-specific
// actions immediately after the connection pool component unlocks a
// connection.
//
property OnUnlockConnection: TNotifyEvent read FOnUnlockConnection write FOnUnlockConnection;
//
// Summary:
// Occurs when a connection pool allocates new connection.
//
// Description:
// Write an OnCreateConnection event handler to take application-specific
// actions immediately after the new connection into pool is allocated.
//
property OnCreateConnection: TNotifyEvent read FOnCreateConnection write FOnCreateConnection;
//
// Summary:
// Occurs when locking a connection into pool is failed.
//
// Description:
// Write an OnLockFail event handler to take application-specific
// actions immediately after the locking connection into pool is failed.
//
property OnLockFail: TExceptionEvent read FOnLockFail write FOnLockFail;
//
// Summary:
// Occurs when a connection pool frees connection.
//
// Description:
// Write an OnFreeConnection event handler to take application-specific
// actions immediately after the connection into pool is freed.
//
property OnFreeConnection: TNotifyEvent read FOnFreeConnection write FOnFreeConnection;
end;

implementation
{$IFDEF TRIAL}
uses
Windows;
{$ENDIF}
{ TPoolConnection }
{- protected ----------------------------------------------------------------- }
procedure TPoolConnection.Lock;
begin
FBusy:= true;
if not Connected then
Connection.Open;
TCustomConnectionPool(TPoolConnections(Collection).Owner).DoLock;
end;

procedure TPoolConnection.Unlock;
begin
FBusy:= false;
TCustomConnectionPool(TPoolConnections(Collection).Owner).DoUnLock;
end;

function TPoolConnection.Connected: Boolean;
begin
Result:= Connection.Connected;
end;

{ - public ------------------------------------------------------------------- }
constructor TPoolConnection.Create(aCollection: TCollection);
begin
inherited;
FConnection:= CreateConnection;
TCustomConnectionPool(TPoolConnections(Collection).Owner).DoCreateConnection;
end;

destructor TPoolConnection.Destroy;
begin
if Busy then
Unlock;
FreeAndNil(FConnection);
TCustomConnectionPool(TPoolConnections(Collection).Owner).DoFreeConnection;
inherited;
end;

{ TPoolConnections }
{ - private ------------------------------------------------------------------ }
function TPoolConnections.GetItem(aIndex: Integer): TPoolConnection;
begin
Result:= inherited GetItem(aIndex) as TPoolConnection;
end;

procedure TPoolConnections.SetItem(aIndex: Integer;
const Value: TPoolConnection);
begin
inherited SetItem(aIndex, Value);
end;

{ - public ------------------------------------------------------------------- }
function TPoolConnections.Add: TPoolConnection;
begin
Result:= inherited Add as TPoolConnection;
end;

{$IFNDEF VER140}
function TPoolConnections.Owner: TPersistent;
begin
Result:= GetOwner;
end;
{$ENDIF}
{ TCustomConnectionPool }
{ - private ------------------------------------------------------------------ }
function TCustomConnectionPool.GetUnusedConnections: LongInt;
var
I: LongInt;
begin
FCS.Enter;
Result:= 0;
try
for I:= 0 to FConnections.Count - 1do
if not FConnections.Busy then
Inc(Result);
finally
FCS.Leave;
end;
end;

function TCustomConnectionPool.GetTotalConnections: LongInt;
begin
Result:= FConnections.Count;
end;

{ - public ------------------------------------------------------------------- }
constructor TCustomConnectionPool.Create(aOwner: TComponent);
begin
inherited;
FCS:= TCriticalSection.Create;
FConnections:= TPoolConnections.Create(Self, GetPoolItemClass);
FMaxConnections:= -1;
end;

destructor TCustomConnectionPool.Destroy;
begin
FCS.Enter;
try
FConnections.Free;
// FreeAndNil(FConnections);
finally
FCS.Leave;
end;
FreeAndNil(FCS);
inherited;
end;

procedure TCustomConnectionPool.AssignTo(Dest: TPersistent);
begin
if Dest is TCustomConnectionPool then
TCustomConnectionPool(Dest).MaxConnections:= MaxConnections
else
inherited AssignTo(Dest);
end;

function TCustomConnectionPool.GetConnection: TCustomConnection;
var
I: LongInt;
begin
Result:= nil;
FCS.Enter;
try
try
I:= 0;
while I < FConnections.Countdo
begin
if not FConnections.Busy then
begin
Result:= FConnections.Connection;
try
FConnections.Lock;
Break;
except
FConnections.Delete(I);
Continue;
end;
end;
Inc(I);
end;

if Result = nil then
if ((FConnections.Count < MaxConnections) or (MaxConnections = -1))
{$IFDEF TRIAL}
and ((FindWindow('TAppBuilder', nil) <> 0) or (FConnections.Count < 3))
{$ENDIF}
then
begin
with FConnections.Adddo
begin
Result:= Connection;
Lock;
end;
end
else
raise Exception.Create('Connection pool limit exceeded.');
except
On E: Exceptiondo
do
LockFail(E);
end;
finally
FCS.Leave;
end;
end;

procedure TCustomConnectionPool.FreeConnection(aConnection: TCustomConnection);
var
I: LongInt;
begin
FCS.Enter;
try
for I:= 0 to FConnections.Count - 1do
if FConnections.Connection = aConnection then
begin
FConnections.Unlock;
Break;
end;
finally
FCS.Leave;
end;
end;

procedure TCustomConnectionPool.DoLock;
begin
if Assigned(FOnLockConnection) then
FOnLockConnection(Self);
end;

procedure TCustomConnectionPool.DoUnlock;
begin
if Assigned(FOnUnLockConnection) then
FOnUnLockConnection(Self);
end;

procedure TCustomConnectionPool.DoCreateConnection;
begin
if Assigned(FOnCreateConnection) then
FOnCreateConnection(Self);
end;

procedure TCustomConnectionPool.DoLockFail(E: Exception);
begin
if Assigned(FOnLockFail) then
FOnLockFail(Self, E);
end;

procedure TCustomConnectionPool.DoFreeConnection;
begin
if Assigned(FOnFreeConnection) then
FOnFreeConnection(Self);
end;


end.
 
仔细找了找我的下载记录,原来是在这里下载的。
http://sms.tomore.com/2/6173.html
ok,公德圆满了。
 
多谢二位回答(kkkchenA/xianguo)
现在的问题是Connection Pool已经有,且有方法取得(如 ConnectionPool.GetConnection), 但不知如何(或何时)能够实现动态切换:
如:
假设在 Connection Pool中的某一个Connection,有三个客户连接(在连接时分别指定)
/ Client 1
Conn1 - Client 2
/ Client 3
若某一时刻三个人同时提交修改内容,如何修改其中的两个至其它的未使用的Connection?
(换种问法就是:如果Client 1 提交了一个操作,需要执行10分钟,在2分钟的时候,如果Client 2 / Client 3 要提交修改, 应该如何处理?)
 
所谓池,就是你有很多相同的东西放在一起,需要的时候向池申请一个,不需要的时候就还给池。你每次向池申请的时候,它把给你的那个实例标记为已用,你把它还个池以后它就把那个实例标记为可分配。在你还没有还给池之前,它是不会再次把它分配给另外的用户的,所以你没必要担心你的实例在同一时刻被多个地方使用。
相信你看过上面给出的代码以后就知道怎么去修改你自己的代码了。
 
为什么不用COM+呢?肯本不用自己实现连接池的功能
 
Thanks [blue]kkkchenA[/blue]:
原系统中间层是由 单 RemoteDateModule (上面放一堆DataSet/Provider之类的控件) + 单 Connection ( 位于主FORM ),
如果我现在将单 Connection 改成 Connection Pool, 请问我该在何时(或如何,或在什么地方)设置连接以及释放连接.
 
你说Connection放在服务器的主Form上,是全部用户都共用一个Connection么?
在RDM上放一个呢,每个用户登陆上来给他一个Connection算了。
这个,好像挺难的啊,不过这样的设计就算是换成了connection Pool也没有什么质的改变啊。程序效率的低下跟Connection没有什么关系,主要是你处理数据的方式造成的这样的局面。你可以用QTime之类的测试软件,看看什么地方占用的大部分的资源,然后对它进行优化。
李维说把DataSet的CacheSize弄到1000去是一个优化的方式之一,你可以试试。
呵呵,我没有好的建议给你。
 
gear123, 这种情况下, 你干脆就将Connect置于RemoteDataModule之上算了, 或者, 改变中间层, 做RemoteDataModule的pool池.
d.s.z.
 
结贴.
多谢各位参与.
[:)][:D][8D][:(][:(!][^][?]
[:)][:D][8D][:(][:(!][^][?]
 

Similar threads

后退
顶部