User: oleg
Date: 00/10/03 10:32:13
Modified: src/main/org/jboss/minerva/xa XAClientConnection.java
Log:
PreparedStatement pool bugfixes:
1) Two wrapper PreparedStatements could use the same "real" one at the same time,
so that ps2.executeQuery() closed the ResultSet obtained by ps1.executeQuery().
Now PreparedStatements are removed from the pool on con.prepareStatement()
and are returned to the pool on ps.close().
2) A PreparedStatement with wrong ResultSetType and ResultSetConcurrency
could be fetched from the pool.
Now ResultSetType and ResultSetConcurrency are included to the pool key.
Revision Changes Path
1.4 +31 -10 jboss/src/main/org/jboss/minerva/xa/XAClientConnection.java
Index: XAClientConnection.java
===================================================================
RCS file:
/products/cvs/ejboss/jboss/src/main/org/jboss/minerva/xa/XAClientConnection.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- XAClientConnection.java 2000/09/29 15:48:36 1.3
+++ XAClientConnection.java 2000/10/03 17:32:13 1.4
@@ -10,6 +10,7 @@
import java.sql.CallableStatement;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
+import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
@@ -31,7 +32,7 @@
* returned to the pool) until the transactional details are taken care of.
* This instance only lives as long as one client is using it - though we
* probably want to consider reusing it to save object allocations.
- * @version $Revision: 1.3 $
+ * @version $Revision: 1.4 $
* @author Aaron Mulder ([EMAIL PROTECTED])
*/
public class XAClientConnection implements ConnectionWrapper {
@@ -97,6 +98,21 @@
*/
public void statementClosed(Statement st) {
statements.remove(st);
+ if (st instanceof PreparedStatementInPool) {
+ // Now return the "real" statement to the pool
+ PreparedStatementInPool ps = (PreparedStatementInPool) st;
+ int rsType = ResultSet.TYPE_FORWARD_ONLY;
+ int rsConcur = ResultSet.CONCUR_READ_ONLY;
+ // We may have JDBC 1.0 driver
+ try {
+ rsType = ps.getResultSetType();
+ rsConcur = ps.getResultSetConcurrency();
+ } catch (Throwable th) {
+ }
+ PreparedStatementInPool.preparedStatementCache.put(
+ new PSCacheKey(con, ps.getSql(), rsType, rsConcur),
+ ps.getUnderlyingPreparedStatement());
+ }
}
// ---- Implementation of java.sql.Connection ----
@@ -115,14 +131,17 @@
public PreparedStatement prepareStatement(String sql) throws SQLException {
if(con == null) throw new SQLException(CLOSED);
try {
- PreparedStatement ps =
(PreparedStatement)PreparedStatementInPool.preparedStatementCache.get(
+ // Seek in the pool and remove if found: the same "real"
PreparedStatement
+ // cannot be used by two wrappers since ps.executeQuery() closes all
+ // ResultSets of the PreparedStatement that may be in use through other
wrappers.
+ // The "real" statement will be returned to the pool on
PreparedStatementInPool.close().
+ PreparedStatement ps =
(PreparedStatement)PreparedStatementInPool.preparedStatementCache.remove(
new PSCacheKey(con, sql));
if(ps == null) {
ps = con.prepareStatement(sql);
- PreparedStatementInPool.preparedStatementCache.put(
- new PSCacheKey(con, sql), ps);
}
- PreparedStatementInPool wrapper = new PreparedStatementInPool(ps, this);
+
+ PreparedStatementInPool wrapper = new PreparedStatementInPool(ps, this,
sql);
statements.add(wrapper);
return wrapper;
} catch(SQLException e) {
@@ -319,14 +338,16 @@
public PreparedStatement prepareStatement(String sql, int resultSetType, int
resultSetConcurrency) throws SQLException {
if(con == null) throw new SQLException(CLOSED);
try {
- PreparedStatement ps =
(PreparedStatement)PreparedStatementInPool.preparedStatementCache.get(
- new PSCacheKey(con, sql));
+ // Seek in the pool and remove if found: the same "real"
PreparedStatement
+ // cannot be used by two wrappers since ps.executeQuery() closes all
+ // ResultSets of the PreparedStatement that may be in use through other
wrappers.
+ // The "real" statement will be returned to the pool on
PreparedStatementInPool.close().
+ PreparedStatement ps =
(PreparedStatement)PreparedStatementInPool.preparedStatementCache.remove(
+ new PSCacheKey(con, sql, resultSetType,
resultSetConcurrency));
if(ps == null) {
ps = con.prepareStatement(sql, resultSetType, resultSetConcurrency);
- PreparedStatementInPool.preparedStatementCache.put(
- new PSCacheKey(con, sql), ps);
}
- PreparedStatementInPool wrapper = new PreparedStatementInPool(ps, this);
+ PreparedStatementInPool wrapper = new PreparedStatementInPool(ps, this,
sql);
statements.add(wrapper);
return wrapper;
} catch(SQLException e) {