Skip to content
Snippets Groups Projects
Commit bccbfb14 authored by Florent Benoit's avatar Florent Benoit
Browse files

Backport patch from trunk for inner statement

fix for #407
parent 643f2f84
No related branches found
No related tags found
No related merge requests found
......@@ -296,6 +296,32 @@ public class ConnectionManagerImpl implements ConnectionEventListener, Connectio
*/
private boolean observable = false;
/**
* Pstmt cache statistic : Pstmt found in cache counter
*/
private long totalPstmtFoundInCache = 0L;
/**
* Pstmt cache statistic : Pstmt put in cache counter
*/
private long totalPstmtPutInCache= 0L;
/**
* Pstmt cache statistic : max nb of jump in cache
*/
private long maxPstmtJumpCache= 0L;
/**
* Pstmt cache statistic : Pstmt freed in cache counter
*/
private long totalPstmtFreedInCache= 0L;
/**
* Pstmt cache statistic : Pstmt created out of cache counter
*/
private long totalPstmtCreatedOutOfCache= 0L;
/**
* ConnectionManagerImpl constructor
* @param transSupport String defining level of support needed
......@@ -435,20 +461,20 @@ public class ConnectionManagerImpl implements ConnectionEventListener, Connectio
/**
* Called by ResourceUtility.createConnectionManager
* to initialize the ConnectionManager with the following parameters:
* RESOURCE_BUNDLE_NAME: Name of the resource bundle to internationalize the logging
* LOGGER: The logger instance where events are logged
* to initialize the ConnectionManager with the following parameters:
* RESOURCE_BUNDLE_NAME: Name of the resource bundle to internationalize the logging
* LOGGER: The logger instance where events are logged
* LOGGER_FACTORY: A logger factory to obtain a logger
* PRINT_WRITER: The printwriter where event are logged
* PRINT_WRITER: The printwriter where event are logged
* TRANSACTION_MANAGER: The Transaction manager linked to this resource manager
* RESOURCE_MANAGER_EVENT_LISTENER: for later connection enlistement.
* RESOURCE_MANAGER_EVENT_LISTENER: for later connection enlistement.
* RESOURCE_ADAPTER: The managedConnectionFactory instance of the resource to be managed
* JNDINAME: JndiName from the factory associated with this ConnectionManager
* @param ctx Description of Parameter
* @param generic RA is generic: No actual pool of Connections
* @exception Exception Description of Exception
*/
public void init(final Context ctx, boolean generic) throws Exception {
public void init(final Context ctx, final boolean generic) throws Exception {
mc2mci = new Hashtable();
// Get the resource bundle name to internationalise the log
......@@ -988,20 +1014,45 @@ public class ConnectionManagerImpl implements ConnectionEventListener, Connectio
break;
}
// counter for statistics
int found = 0; // found in cache
int cached = 0; // put in cache
int jumpNb = 0; // number of jumper to find or not
int freed = 0; // an entry was freed
int created = 0; // an entry was created out of the cache
try {
synchronized (mcinfo.pStmts) {
if (isEnabledDebug) {
trace.log(BasicLevel.DEBUG, "MC pStmts: " + mcinfo.pStmts);
}
//Check if statement matches ManagedConnection list & valid
// use lastIndexOf as when a statement is found, it is put at the end.
int indexPstmt = mcinfo.pStmts.lastIndexOf(psw);
if (indexPstmt != -1) {
PreparedStatementWrapper ps = (PreparedStatementWrapper) mcinfo.pStmts.remove(indexPstmt);
ps.clearPstmtValues();
mcinfo.pStmts.add(ps); // add last
return ps;
} else if (isEnabledDebug) {
trace.log(BasicLevel.DEBUG, "No statement in cache, need to build a new one");
while (indexPstmt != -1) {
PreparedStatementWrapper ps = (PreparedStatementWrapper) mcinfo.pStmts.get(indexPstmt);
if (ps.isClosed()) {
ps = (PreparedStatementWrapper) mcinfo.pStmts.remove(indexPstmt);
ps.clearPstmtValues();
mcinfo.pStmts.add(ps); // add last
found++;
return ps;
} else {
jumpNb++;
if (isEnabledDebug) {
trace.log(BasicLevel.DEBUG, "Statement in cache but already used, search another one");
trace.log(BasicLevel.DEBUG, "sql=" + sql + ", count=" + jumpNb);
}
// next element
indexPstmt = mcinfo.pStmts.subList(0,indexPstmt).lastIndexOf(psw);
}
}
if (isEnabledDebug) {
trace.log(BasicLevel.DEBUG, "No statement in cache (or not closed), need to build a new one");
}
//If not in either, call con.prepareStatement, wrap the returned one
......@@ -1033,6 +1084,7 @@ public class ConnectionManagerImpl implements ConnectionEventListener, Connectio
break;
}
if (maxPstmtPoolSize < 0) {
created++;
// No prepared statement pool
if (isEnabledDebug) {
trace.log(BasicLevel.DEBUG, "Pooling is disabled");
......@@ -1041,6 +1093,7 @@ public class ConnectionManagerImpl implements ConnectionEventListener, Connectio
} else if (maxPstmtPoolSize == 0 || mcinfo.pStmts.size() < maxPstmtPoolSize) {
psw.setPreparedStatement(ps);
mcinfo.pStmts.add(psw);
cached++;
if (isEnabledDebug) {
trace.log(BasicLevel.DEBUG, "Adding PStmt: " + psw);
}
......@@ -1048,11 +1101,13 @@ public class ConnectionManagerImpl implements ConnectionEventListener, Connectio
} else {
int offset = mcinfo.findFreeStmt();
if (offset >= 0) {
// Remove that entry from the current pool
// Remove that entry from the current pool and add it at the end of the list
PreparedStatementWrapper pw = (PreparedStatementWrapper) mcinfo.pStmts.remove(offset);
pw.destroy();
freed++;
psw.setPreparedStatement(ps);
mcinfo.pStmts.add(psw);
cached++;
if (isEnabledDebug) {
trace.log(BasicLevel.DEBUG, "Replacing " + pw + " with " + psw);
}
......@@ -1062,10 +1117,14 @@ public class ConnectionManagerImpl implements ConnectionEventListener, Connectio
if (isEnabledDebug) {
trace.log(BasicLevel.DEBUG, "No room in pool");
}
created++;
return ps;
}
}
}
} finally {
updatePstmtCacheStatistics(found,cached,jumpNb,freed,created);
}
}
......@@ -1100,6 +1159,38 @@ public class ConnectionManagerImpl implements ConnectionEventListener, Connectio
if (isEnabledDebug) {
trace.log(BasicLevel.DEBUG, "ManagedConnectionInfo: " + mcinfo);
}
int freed = 0;
try {
synchronized (mcinfo.pStmts) {
if (mcinfo.pStmts.size() <= 0) {
return;
}
int stmtSize = mcinfo.pStmts.size();
try {
for (int i = 0; i < stmtSize; i++) {
PreparedStatementWrapper psw = (PreparedStatementWrapper) mcinfo.pStmts.remove(0);
freed++;
psw.closePstmt();
}
} catch (Exception ex) {
throw ex;
}
}
} finally {
updatePstmtCacheStatistics(0,0,0,freed,0);
}
}
/**
* Closing of the PreparedStatement objects of the Pool
* @param mcinfo ManagedConnection information
* @throws Exception Exception
*/
public void closePStmts(final ManagedConnectionInfo mcinfo) throws Exception {
if (isEnabledDebug) {
trace.log(BasicLevel.DEBUG, "ManagedConnectionInfo: " + mcinfo);
}
synchronized (mcinfo.pStmts) {
if (mcinfo.pStmts.size() <= 0) {
return;
......@@ -1108,8 +1199,8 @@ public class ConnectionManagerImpl implements ConnectionEventListener, Connectio
try {
for (int i = 0; i < stmtSize; i++) {
PreparedStatementWrapper psw = (PreparedStatementWrapper)
mcinfo.pStmts.remove(0);
psw.closePstmt();
mcinfo.pStmts.get(i);
psw.close();
}
} catch (Exception ex) {
throw ex;
......@@ -1117,6 +1208,7 @@ public class ConnectionManagerImpl implements ConnectionEventListener, Connectio
}
}
/**
* IMPLEMENTATION OF INTERFACE ConnectionEventListener *
*
......@@ -1165,6 +1257,10 @@ public class ConnectionManagerImpl implements ConnectionEventListener, Connectio
}
if (currentTx != null) {
if (isEnabledDebug) {
trace.log(BasicLevel.DEBUG, "currentTx=" + currentTx);
}
Transaction oldtx = (Transaction) mci.getGlobalTx();
if (oldtx != null && oldtx != currentTx) {
trace.log(BasicLevel.DEBUG, "This connection was used by another tx");
......@@ -1189,6 +1285,10 @@ public class ConnectionManagerImpl implements ConnectionEventListener, Connectio
// but the synchronization is registered.
trace.log(BasicLevel.INFO, "registerSynchronization on transaction marked as Rollback only, mc=" + mci.mc);
}
} else {
if (isEnabledDebug) {
trace.log(BasicLevel.DEBUG, "synchro mc=" + mci.mc);
}
}
} else if (mci.localTransaction) {
if (isEnabledDebug) {
......@@ -1207,6 +1307,9 @@ public class ConnectionManagerImpl implements ConnectionEventListener, Connectio
mci.setGlobalTx(null);
}
// force close pstmt
closePStmts(mci);
mci.mc.cleanup();
// Release the MC from its pool
......@@ -1341,6 +1444,10 @@ public class ConnectionManagerImpl implements ConnectionEventListener, Connectio
}
try {
// force close pstmt
closePStmts(mci);
mci.mc.cleanup();
// Release the MC from its pool
......@@ -1398,6 +1505,9 @@ public class ConnectionManagerImpl implements ConnectionEventListener, Connectio
}
try {
// force close pstmt
closePStmts(mci);
mci.mc.cleanup();
// Release the MC from its pool
......@@ -1616,6 +1726,9 @@ public class ConnectionManagerImpl implements ConnectionEventListener, Connectio
}
try {
// force close pstmt
closePStmts(mci);
mci.mc.cleanup();
// Release the MC from its pool
......@@ -1656,17 +1769,17 @@ public class ConnectionManagerImpl implements ConnectionEventListener, Connectio
}
/**
* @return the observable
*/
public boolean isObservable() {
return observable;
}
* @return the observable
*/
public boolean isObservable() {
return observable;
}
/**
* @param observable the observable to set
*/
public void setObservable(final boolean observable) {
this.observable = observable;
/**
* @param observable the observable to set
*/
public void setObservable(final boolean observable) {
this.observable = observable;
// must propagate to the pool
if (poolMCs != null) {
poolMCs.setObservable(observable);
......@@ -1764,4 +1877,64 @@ public class ConnectionManagerImpl implements ConnectionEventListener, Connectio
public List getManagedConnectionsWithoutTransaction() {
return mcs;
}
/**
* Update statistics about pstmt cache (synchronized)
* @param found : nb of element found in cache
* @param cached : nb of elements put in cache
* @param jumpNb : number of jump to find an element in the cache
* @param freed : number of element freed in cache
* @param created : number of element created out of the cache
*/
public synchronized void updatePstmtCacheStatistics(final int found, final int cached, final int jumpNb, final int freed, final int created) {
totalPstmtFoundInCache += found;
totalPstmtPutInCache += cached;
if (jumpNb > maxPstmtJumpCache) {
maxPstmtJumpCache = jumpNb;
}
totalPstmtFreedInCache += freed;
totalPstmtCreatedOutOfCache += created;
}
/**
* @return total number of pstmt found in cache
*
*/
public long getTotalPstmtFoundInCache() {
return totalPstmtFoundInCache;
}
/**
* @return total number of pstmt put in cache
*
*/
public long getTotalPstmtPutInCache() {
return totalPstmtPutInCache;
}
/**
* @return total number of jump in cache to found a pstmt
*
*/
public long getMaxPstmtJumpCache() {
return maxPstmtJumpCache;
}
/**
* @return total number of pstmt freed in cache
*
*/
public long getTotalPstmtFreedInCache() {
return totalPstmtFreedInCache;
}
/**
* @return total number of pstmt created out of the cache
*
*/
public long getTotalPstmtCreatedOutOfCache() {
return totalPstmtCreatedOutOfCache;
}
}
......@@ -25,17 +25,16 @@
package org.ow2.jonas.resource.internal.cm.jta;
import java.util.Iterator;
import java.util.Map;
import javax.resource.spi.ManagedConnection;
import javax.transaction.Synchronization;
import org.objectweb.util.monolog.api.BasicLevel;
import org.ow2.jonas.resource.internal.cm.ConnectionManagerImpl;
import org.ow2.jonas.resource.internal.cm.ManagedConnectionInfo;
import org.objectweb.util.monolog.api.BasicLevel;
import java.util.Iterator;
import java.util.Map;
/**
* This class is an implementation of the {@link Synchronization} interface, used by a
* {@link ConnectionManagerImpl} instance. The aim of this class is to close a
......@@ -66,7 +65,7 @@ public class JSynchronization implements Synchronization {
*@param pMci ManagedConnection information object
*
*/
public JSynchronization(ConnectionManagerImpl pCm, ManagedConnectionInfo pMci) {
public JSynchronization(final ConnectionManagerImpl pCm, final ManagedConnectionInfo pMci) {
mci = pMci;
cm = pCm;
mci.synchro = this;
......@@ -80,7 +79,7 @@ public class JSynchronization implements Synchronization {
*
*@param status The transaction flag
*/
public void afterCompletion(int status) {
public void afterCompletion(final int status) {
if (mci == null) {
return;
}
......@@ -113,6 +112,10 @@ public class JSynchronization implements Synchronization {
}
mci.setGlobalTx(null);
// force close pstmt
cm.closePStmts(mci);
mci.mc.cleanup();
cm.getPool().releaseResource(mci.mc, false);
......
......@@ -434,11 +434,11 @@ public class JCAConnectionFactory extends J2EEManagedObject {
}
public void setObservable(final boolean observable) {
cm.setObservable(observable);
cm.setObservable(observable);
}
public boolean isObservable() {
return cm.isObservable();
return cm.isObservable();
}
/**
......@@ -455,4 +455,45 @@ public class JCAConnectionFactory extends J2EEManagedObject {
public String getFileName() {
return fileName;
}
/**
* @return total number of pstmt found in cache
*
*/
public long getTotalPstmtFoundInCache() {
return cm.getTotalPstmtFoundInCache();
}
/**
* @return total number of pstmt put in cache
*
*/
public long getTotalPstmtPutInCache() {
return cm.getTotalPstmtPutInCache();
}
/**
* @return max number of jump in cache to found a pstmt
*
*/
public long getMaxPstmtJumpCache() {
return cm.getMaxPstmtJumpCache();
}
/**
* @return total number of pstmt freed in cache
*
*/
public long getTotalPstmtFreedInCache() {
return cm.getTotalPstmtFreedInCache();
}
/**
* @return total number of pstmt created out of the cache
*
*/
public long getTotalPstmtCreatedOutOfCache() {
return cm.getTotalPstmtCreatedOutOfCache();
}
}
......@@ -464,6 +464,31 @@
writeable="true"
is="true" />
<attribute name="totalPstmtFoundInCache"
description="total number of pstmt found in cache"
type="java.lang.Long"
writeable="false"/>
<attribute name="totalPstmtPutInCache"
description="total number of pstmt put in cache"
type="java.lang.Long"
writeable="false"/>
<attribute name="maxPstmtJumpCache"
description="max number of jump to found a pstmt in cache"
type="java.lang.Long"
writeable="false"/>
<attribute name="totalPstmtFreedInCache"
description="total number of pstmt freed in cache"
type="java.lang.Long"
writeable="false"/>
<attribute name="totalPstmtCreatedOutOfCache"
description="total number of pstmt created out of the cache"
type="java.lang.Long"
writeable="false"/>
<!-- Fine JDBC Connection handling operations -->
<operation name="getOpenedConnections"
description="Show the opened physical connections being used for more than a given amount of time (sec)."
......@@ -498,7 +523,7 @@
type="int"
description="The identifier of the JDBC Connection to be closed." />
</operation>
</mbean>
<mbean name="JCAManagedConnectionFactory"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment