Skip to content

Commit 68a31e2

Browse files
committed
Updated the ConnectionPool class to manage javaxt.sql.Connections instead of java.sql.Connections. Removed the getRawConnection() method introduced in an earlier commit.
1 parent 73ee3a0 commit 68a31e2

File tree

1 file changed

+75
-62
lines changed

1 file changed

+75
-62
lines changed

src/javaxt/sql/ConnectionPool.java

Lines changed: 75 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -134,35 +134,16 @@ public ConnectionPool(ConnectionPoolDataSource dataSource, int maxConnections, M
134134
/** Retrieves a connection from the connection pool. If all the connections
135135
* are in use, the method waits until a connection becomes available or
136136
* <code>timeout</code> seconds elapsed. When the application is finished
137-
* using the connection, it must ne closed in order to return it to the pool.
137+
* using the connection, it must be closed in order to return it to the
138+
* pool.
138139
*/
139140
public Connection getConnection() throws SQLException {
140-
java.sql.Connection conn = getRawConnection();
141-
if (conn == null) {
142-
return null;
143-
}
144-
else{
145-
Connection c = new Connection();
146-
c.open(conn, database);
147-
return c;
148-
}
149-
}
150-
151-
152-
//**************************************************************************
153-
//** getRawConnection
154-
//**************************************************************************
155-
/** Retrieves a raw, java.sql.Connection from the connection pool. This
156-
* method is called by the getConnection() method which simply wraps the
157-
* java.sql.Connection into a javaxt.sql.Connection.
158-
*/
159-
public java.sql.Connection getRawConnection() throws SQLException {
160141
long time = System.currentTimeMillis();
161142
long timeoutTime = time + timeoutMs;
162143
int triesWithoutDelay = getInactiveConnections() + 1;
163144

164145
while (true) {
165-
java.sql.Connection conn = getConnection(time, timeoutTime);
146+
Connection conn = getConnection(time, timeoutTime);
166147
if (conn != null) {
167148
return conn;
168149
}
@@ -306,7 +287,7 @@ public void close() throws SQLException {
306287
// Use disposeConnection to properly handle the totalConnectionCount decrement
307288
PooledConnectionWrapper wrapper;
308289
while ((wrapper = recycledConnections.poll()) != null) {
309-
disposeConnection(wrapper.connection);
290+
disposeConnection(wrapper.pooledConnection);
310291
}
311292

312293
connectionWrappers.clear();
@@ -377,11 +358,11 @@ private void init(ConnectionPoolDataSource dataSource, int maxConnections, Map<S
377358
//**************************************************************************
378359
//** getConnection
379360
//**************************************************************************
380-
private java.sql.Connection getConnection(long time, long timeoutTime) {
361+
private Connection getConnection(long time, long timeoutTime) {
381362
long rtime = Math.max(1, timeoutTime - time);
382-
java.sql.Connection conn;
363+
Connection connection;
383364
try {
384-
conn = acquireConnection(rtime);
365+
connection = acquireConnection(rtime);
385366
}
386367
catch (SQLException e) {
387368
return null;
@@ -391,9 +372,11 @@ private java.sql.Connection getConnection(long time, long timeoutTime) {
391372
rtime = timeoutTime - System.currentTimeMillis();
392373
int rtimeSecs = Math.max(1, (int)((rtime + 999) / 1000));
393374

375+
// Validate using the underlying raw connection
376+
java.sql.Connection rawConn = connection.getConnection();
394377
try {
395-
if (conn.isValid(rtimeSecs)) {
396-
return conn;
378+
if (rawConn.isValid(rtimeSecs)) {
379+
return connection;
397380
}
398381
}
399382
catch (SQLException e) {
@@ -406,15 +389,15 @@ private java.sql.Connection getConnection(long time, long timeoutTime) {
406389
// and the PooledConnection has been removed from the pool, i.e. the PooledConnection will
407390
// not be added to recycledConnections when Connection.close() is called.
408391
// But to be sure that this works even with a faulty JDBC driver, we call purgeConnection().
409-
purgeConnection(conn);
392+
purgeConnection(rawConn);
410393
return null;
411394
}
412395

413396

414397
//**************************************************************************
415398
//** acquireConnection
416399
//**************************************************************************
417-
private java.sql.Connection acquireConnection(long timeoutMs) throws SQLException {
400+
private Connection acquireConnection(long timeoutMs) throws SQLException {
418401
if (isDisposed.get()) {
419402
throw new IllegalStateException("Connection pool has been disposed.");
420403
}
@@ -424,7 +407,7 @@ private java.sql.Connection acquireConnection(long timeoutMs) throws SQLExceptio
424407

425408
while (System.currentTimeMillis() < timeoutTime) {
426409
// First, try to get a recycled connection
427-
java.sql.Connection recycledConn = getRecycledConnection();
410+
Connection recycledConn = getRecycledConnection();
428411
if (recycledConn != null) {
429412
return recycledConn;
430413
}
@@ -435,7 +418,7 @@ private java.sql.Connection acquireConnection(long timeoutMs) throws SQLExceptio
435418
if (currentTotal < maxConnections) {
436419
if (totalConnections.compareAndSet(currentTotal, currentTotal + 1)) {
437420
try {
438-
java.sql.Connection conn = createNewConnection();
421+
Connection conn = createNewConnection();
439422
if (conn != null) {
440423
return conn;
441424
} else {
@@ -466,13 +449,13 @@ private java.sql.Connection acquireConnection(long timeoutMs) throws SQLExceptio
466449
//**************************************************************************
467450
//** getRecycledConnection
468451
//**************************************************************************
469-
private java.sql.Connection getRecycledConnection() throws SQLException {
452+
private Connection getRecycledConnection() throws SQLException {
470453
PooledConnectionWrapper wrapper = recycledConnections.poll();
471454
if (wrapper == null) {
472455
return null; // No recycled connections available
473456
}
474457

475-
PooledConnection pconn = wrapper.connection;
458+
PooledConnection pconn = wrapper.pooledConnection;
476459

477460
// Skip all validation for very recently recycled connections (< 5 seconds)
478461
// This dramatically improves performance for high-frequency connection reuse scenarios
@@ -500,20 +483,27 @@ private java.sql.Connection getRecycledConnection() throws SQLException {
500483
}
501484
}
502485

503-
// Connection is valid, update its usage time and return it
486+
// Connection is valid, update its usage time
504487
wrapper = wrapper.markUsed();
505488
connectionWrappers.put(pconn, wrapper);
506489

507-
java.sql.Connection conn;
508490
try {
509491
connectionInTransition = pconn;
510-
activeConnections.incrementAndGet(); // Increment before getConnection() to ensure it's always counted
511-
conn = pconn.getConnection();
492+
activeConnections.incrementAndGet(); // Increment before getting connection
493+
494+
// Get a fresh logical connection from the PooledConnection
495+
java.sql.Connection rawConn = pconn.getConnection();
496+
497+
// Re-open the javaxt.sql.Connection wrapper with the fresh logical connection
498+
// This updates the underlying connection reference without creating a new wrapper object
499+
wrapper.connection.open(rawConn, database);
500+
501+
return wrapper.connection; // Return reused wrapper with fresh connection
512502
} catch (SQLException e) {
513503
connectionInTransition = null;
514-
// Connection failed, decrement the activeConnections counter we just incremented
504+
// Failed, decrement the activeConnections counter we just incremented
515505
activeConnections.decrementAndGet();
516-
// Connection failed, dispose it
506+
// Dispose the wrapper
517507
connectionWrappers.remove(pconn);
518508
doPurgeConnection.set(true);
519509
try {
@@ -529,25 +519,34 @@ private java.sql.Connection getRecycledConnection() throws SQLException {
529519
} finally {
530520
connectionInTransition = null;
531521
}
532-
533-
return conn;
534522
}
535523

536-
private java.sql.Connection createNewConnection() throws SQLException {
537-
PooledConnection pconn = null;
524+
525+
//**************************************************************************
526+
//** createNewConnection
527+
//**************************************************************************
528+
private Connection createNewConnection() throws SQLException {
529+
PooledConnection pconn;
538530
try {
539531
pconn = dataSource.getPooledConnection();
540532
pconn.addConnectionEventListener(poolConnectionEventListener);
541-
PooledConnectionWrapper wrapper = new PooledConnectionWrapper(pconn);
542-
connectionWrappers.put(pconn, wrapper);
543533

544-
java.sql.Connection conn;
534+
Connection connection;
545535
try {
546536
connectionInTransition = pconn;
547537
activeConnections.incrementAndGet(); // Increment before getConnection() to ensure it's always counted
548-
conn = pconn.getConnection();
538+
539+
// Get raw connection and wrap it ONCE
540+
java.sql.Connection rawConn = pconn.getConnection();
541+
connection = new Connection();
542+
connection.open(rawConn, database);
543+
544+
// Store the pre-wrapped connection for reuse
545+
PooledConnectionWrapper wrapper = new PooledConnectionWrapper(connection, pconn);
546+
connectionWrappers.put(pconn, wrapper);
547+
549548
// totalConnections was already incremented in acquireConnection
550-
return conn;
549+
return connection;
551550
} catch (SQLException e) {
552551
connectionInTransition = null;
553552
// Connection creation failed, decrement the activeConnections counter we just incremented
@@ -642,7 +641,7 @@ private void performHealthCheck() {
642641
// Process connections and re-add valid ones
643642
for (PooledConnectionWrapper w : toCheck) {
644643
if (w.isIdle(connectionIdleTimeoutMs) || w.isExpired(connectionMaxAgeMs)) {
645-
disposeConnection(w.connection);
644+
disposeConnection(w.pooledConnection);
646645
removedCount++;
647646
log("Removed " + (w.isExpired(connectionMaxAgeMs) ? "expired" : "idle") +
648647
" connection from pool. Age: " + (now - w.createdTime) + "ms");
@@ -694,9 +693,20 @@ private void performHealthCheck() {
694693
pconn.addConnectionEventListener(poolConnectionEventListener);
695694

696695
if (validateConnection(pconn)) {
697-
PooledConnectionWrapper w = new PooledConnectionWrapper(pconn);
696+
// Create and wrap connection for warm-up
697+
java.sql.Connection rawConn = pconn.getConnection();
698+
Connection connection = new Connection();
699+
connection.open(rawConn, database);
700+
701+
// Store the wrapper (but don't add to recycled yet - it's active)
702+
PooledConnectionWrapper w = new PooledConnectionWrapper(connection, pconn);
698703
connectionWrappers.put(pconn, w);
699-
recycledConnections.offer(w);
704+
705+
// Close the connection to recycle it
706+
// This will trigger connectionClosed event which calls recycleConnection()
707+
// recycleConnection() will add it to the recycled queue
708+
rawConn.close();
709+
700710
currentRecycled++;
701711
total = currentActive + currentRecycled;
702712
log("Pool warm-up: added connection " + currentRecycled + "/" + minConnections);
@@ -812,13 +822,13 @@ private void recycleConnection (PooledConnection pconn) {
812822
PooledConnectionWrapper wrapper = connectionWrappers.get(pconn);
813823
if (wrapper != null) {
814824
// Update the wrapper with current usage time and add to recycled connections
825+
// The javaxt.sql.Connection wrapper is reused - no new object creation!
815826
wrapper = wrapper.markUsed();
816827
recycledConnections.offer(wrapper);
817828
}
818829
else {
819-
// Fallback: create new wrapper if not found (shouldn't happen in normal operation)
820-
wrapper = new PooledConnectionWrapper(pconn);
821-
recycledConnections.offer(wrapper);
830+
// This shouldn't happen in normal operation - log a warning
831+
log("Warning: Wrapper not found for PooledConnection during recycle");
822832
}
823833

824834
// Connection successfully recycled
@@ -846,7 +856,7 @@ private void disposeConnection (PooledConnection pconn) {
846856
// Try to remove from recycled connections
847857
boolean foundInRecycled = false;
848858
for (PooledConnectionWrapper wrapper : recycledConnections) {
849-
if (wrapper.connection == pconn) {
859+
if (wrapper.pooledConnection == pconn) {
850860
if (recycledConnections.remove(wrapper)) {
851861
foundInRecycled = true;
852862
}
@@ -885,8 +895,8 @@ private void disposeConnection (PooledConnection pconn) {
885895
//** log
886896
//**************************************************************************
887897
private void log(String msg) {
888-
String s = "ConnectionPool: "+msg;
889-
try {
898+
String s = "ConnectionPool: "+msg;
899+
try {
890900
if (logWriter == null) {
891901
//System.err.println(s);
892902
}
@@ -943,18 +953,21 @@ public void connectionErrorOccurred (ConnectionEvent event) {
943953
/** Wrapper class to track connection metadata
944954
*/
945955
private static class PooledConnectionWrapper {
946-
final PooledConnection connection;
956+
final Connection connection;
957+
final PooledConnection pooledConnection;
947958
final long createdTime;
948959
final long lastUsedTime;
949960

950-
PooledConnectionWrapper(PooledConnection connection) {
961+
PooledConnectionWrapper(Connection connection, PooledConnection pooledConnection) {
951962
this.connection = connection;
963+
this.pooledConnection = pooledConnection;
952964
this.createdTime = System.currentTimeMillis();
953965
this.lastUsedTime = System.currentTimeMillis();
954966
}
955967

956-
PooledConnectionWrapper(PooledConnection connection, long createdTime, long lastUsedTime) {
968+
PooledConnectionWrapper(Connection connection, PooledConnection pooledConnection, long createdTime, long lastUsedTime) {
957969
this.connection = connection;
970+
this.pooledConnection = pooledConnection;
958971
this.createdTime = createdTime;
959972
this.lastUsedTime = lastUsedTime;
960973
}
@@ -968,7 +981,7 @@ boolean isExpired(long maxAgeMs) {
968981
}
969982

970983
PooledConnectionWrapper markUsed() {
971-
return new PooledConnectionWrapper(connection, createdTime, System.currentTimeMillis());
984+
return new PooledConnectionWrapper(connection, pooledConnection, createdTime, System.currentTimeMillis());
972985
}
973986
}
974987

0 commit comments

Comments
 (0)