mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 17:23:03 +01:00
Reset external connection before put it into pool.
Update the documentation.
This commit is contained in:
parent
2930edb9c0
commit
d681f5288f
@ -9,10 +9,13 @@ Author:
|
||||
Vlad Khorsun <hvlad@users.sourceforge.net>
|
||||
|
||||
How pool works:
|
||||
- every external connection is assotiated with a pool when created
|
||||
- pool maintains two lists : idle connections and active connections
|
||||
- when some connection gets unused (i.e. it have no active requests and
|
||||
active transactions), it puts into idle list
|
||||
- every external connection is associated with a pool when created
|
||||
- pool maintains two lists: idle connections and active connections
|
||||
- when some connection become unused (i.e. it have no active requests and no
|
||||
active transactions), it is resetted and placed into idle list (on successful
|
||||
reset) or closed (if reset failed).
|
||||
Connection is resetted using ALTER SESSION RESET statement. It is considered
|
||||
successful if no error occurs.
|
||||
- if the pool has reached max. size, the oldest idle connection is closed
|
||||
- when engine ask to create a new external connection, the pool first looks
|
||||
for candidate at the idle list. The search is based on 4 parameters:
|
||||
@ -26,7 +29,7 @@ How pool works:
|
||||
(the error is not reported to the user)
|
||||
- found (and alive) connection is moved from idle list to active list and
|
||||
returned to the caller
|
||||
- if there are several suitable connections, the most recently used is choosed
|
||||
- if there are several suitable connections, the most recently used is chosen
|
||||
- if there is no suitable connection, the new one is created (and put into
|
||||
active list)
|
||||
- when idle connection gets expired (exceeded the lifetime), it is deleted from
|
||||
@ -41,16 +44,16 @@ Key characteristics:
|
||||
process
|
||||
|
||||
Pool parameters:
|
||||
- connection life time : the time interval from the moment of the last usage of
|
||||
- connection life time: the time interval from the moment of the last usage of
|
||||
connection after which it will be forcibly closed
|
||||
- pool size : the maximum allowed number of idle connections in the pool
|
||||
- pool size: the maximum allowed number of idle connections in the pool
|
||||
|
||||
Pool management:
|
||||
New SQL statement is introduced to manage the pool :
|
||||
New SQL statement is introduced to manage the pool:
|
||||
|
||||
ALTER EXTERNAL CONNECTIONS POOL.
|
||||
|
||||
When prepared it desribed as DDL statement but have immediate effect: i.e.
|
||||
When prepared it is described as DDL statement but have immediate effect: i.e.
|
||||
it is executed immediately and completely, not waiting for transaction commit.
|
||||
Changes applied to the in-memory instance of the pool in current Firebird
|
||||
process. Therefore change in one Classic process doesn't affect other Classic
|
||||
@ -72,12 +75,12 @@ The full syntax is:
|
||||
where <time_part> is SECOND | MINUTE | HOUR
|
||||
|
||||
Set idle connection lifetime, in seconds.
|
||||
Valid valus are from 1 SECOND to 24 HOUR.
|
||||
Valid values are from 1 SECOND to 24 HOUR.
|
||||
Default value is set in firebird.conf (see below).
|
||||
|
||||
- ALTER EXTERNAL CONNECTIONS POOL CLEAR ALL
|
||||
Closes all idle connections.
|
||||
Disassotiates all active connections off the pool (such connections will be
|
||||
Disassociates all active connections off the pool (such connections will be
|
||||
closed immediately when gets unused).
|
||||
|
||||
- ALTER EXTERNAL CONNECTIONS POOL CLEAR OLDEST
|
||||
@ -88,7 +91,7 @@ variables in 'SYSTEM' namespace:
|
||||
- EXT_CONN_POOL_SIZE pool size
|
||||
- EXT_CONN_POOL_LIFETIME idle connection lifetime, in seconds
|
||||
- EXT_CONN_POOL_IDLE_COUNT count of currently inactive connections
|
||||
- EXT_CONN_POOL_ACTIVE_COUNT count of active connections, assotiated with pool
|
||||
- EXT_CONN_POOL_ACTIVE_COUNT count of active connections, associated with pool
|
||||
|
||||
|
||||
Firebird configuration (firebird.conf) got two new settings related with pool:
|
||||
|
@ -445,10 +445,18 @@ void Provider::releaseConnection(thread_db* tdbb, Connection& conn, bool inPool)
|
||||
m_connections.add(AttToConn(NULL, &conn));
|
||||
}
|
||||
|
||||
if (!inPool || !connPool || !conn.isConnected())
|
||||
if (!inPool || !connPool || !conn.isConnected() || !conn.resetSession())
|
||||
{
|
||||
if (connPool)
|
||||
{
|
||||
{
|
||||
MutexLockGuard guard(m_mutex, FB_FUNCTION);
|
||||
AttToConnMap::Accessor acc(&m_connections);
|
||||
if (acc.locate(AttToConn(NULL, &conn)))
|
||||
acc.fastRemove();
|
||||
}
|
||||
connPool->delConnection(tdbb, &conn, false);
|
||||
}
|
||||
|
||||
Connection::deleteConnection(tdbb, &conn);
|
||||
}
|
||||
|
@ -420,6 +420,7 @@ public:
|
||||
virtual void detach(Jrd::thread_db* tdbb);
|
||||
|
||||
virtual bool cancelExecution(bool forced) = 0;
|
||||
virtual bool resetSession() = 0;
|
||||
|
||||
int getSqlDialect() const { return m_sqlDialect; }
|
||||
|
||||
|
@ -239,6 +239,20 @@ bool InternalConnection::cancelExecution(bool /*forced*/)
|
||||
return !(status->getState() & IStatus::STATE_ERRORS);
|
||||
}
|
||||
|
||||
bool InternalConnection::resetSession()
|
||||
{
|
||||
fb_assert(!m_isCurrent);
|
||||
|
||||
if (m_isCurrent)
|
||||
return true;
|
||||
|
||||
FbLocalStatus status;
|
||||
m_attachment->execute(&status, NULL, 0, "ALTER SESSION RESET",
|
||||
m_sqlDialect, NULL, NULL, NULL, NULL);
|
||||
|
||||
return !(status->getState() & IStatus::STATE_ERRORS);
|
||||
}
|
||||
|
||||
// this internal connection instance is available for the current execution context if it
|
||||
// a) is current connection and current thread's attachment is equal to
|
||||
// this attachment, or
|
||||
|
@ -67,6 +67,7 @@ public:
|
||||
virtual void attach(Jrd::thread_db* tdbb);
|
||||
|
||||
virtual bool cancelExecution(bool forced);
|
||||
virtual bool resetSession();
|
||||
|
||||
virtual bool isAvailable(Jrd::thread_db* tdbb, TraScope traScope) const;
|
||||
|
||||
|
@ -239,6 +239,21 @@ bool IscConnection::cancelExecution(bool forced)
|
||||
return !(status->getState() & IStatus::STATE_ERRORS);
|
||||
}
|
||||
|
||||
bool IscConnection::resetSession()
|
||||
{
|
||||
if (!m_handle)
|
||||
return false;
|
||||
|
||||
FbLocalStatus status;
|
||||
m_iscProvider.isc_dsql_execute_immediate(&status, &m_handle,
|
||||
NULL, 0, "ALTER SESSION RESET", m_sqlDialect, NULL);
|
||||
|
||||
if (!(status->getState() & IStatus::STATE_ERRORS))
|
||||
return true;
|
||||
|
||||
return false; // (status->getErrors()[1] == isc_dsql_error);
|
||||
}
|
||||
|
||||
// this ISC connection instance is available for the current execution context if it
|
||||
// a) has no active statements or supports many active statements
|
||||
// and
|
||||
@ -1111,14 +1126,14 @@ ISC_STATUS ISC_EXPORT IscProvider::isc_dsql_execute2(FbStatusVector* user_status
|
||||
}
|
||||
|
||||
ISC_STATUS ISC_EXPORT IscProvider::isc_dsql_execute_immediate(FbStatusVector* user_status,
|
||||
isc_db_handle *,
|
||||
isc_tr_handle *,
|
||||
unsigned short,
|
||||
const char*,
|
||||
unsigned short,
|
||||
const XSQLDA *)
|
||||
isc_db_handle* db_handle, isc_tr_handle* tra_handle, unsigned short length,
|
||||
const char* str, unsigned short dialect, const XSQLDA* sqlda)
|
||||
{
|
||||
return notImplemented(user_status);
|
||||
if (!m_api.isc_dsql_execute_immediate)
|
||||
return notImplemented(user_status);
|
||||
|
||||
return (*m_api.isc_dsql_execute_immediate) (IscStatus(user_status),
|
||||
db_handle, tra_handle, length, str, dialect, sqlda);
|
||||
}
|
||||
|
||||
ISC_STATUS ISC_EXPORT IscProvider::isc_dsql_fetch(FbStatusVector* user_status,
|
||||
|
@ -519,6 +519,7 @@ public:
|
||||
virtual void attach(Jrd::thread_db* tdbb);
|
||||
|
||||
virtual bool cancelExecution(bool forced);
|
||||
virtual bool resetSession();
|
||||
|
||||
virtual bool isAvailable(Jrd::thread_db* tdbb, TraScope traScope) const;
|
||||
virtual bool isConnected() const { return (m_handle != 0); }
|
||||
|
Loading…
Reference in New Issue
Block a user