Comments (8)
If you can submit a pull request it would be greatly appreciated.
from btm.
Brett, I am trying to think of the best way of fixing this. It seems closely coupled with my "PreparedStatement leak" issue, because the root of both problems is that the LruStatementCache contains proxy objects instead of the underlying PreparedStatement objects from the DB driver. So I was thinking of modifying all of the "prepareStatement()" functions in ConnectionJavaProxy like this:
if (useStatementCache) {
CacheKey cacheKey = new CacheKey(sql);
PreparedStatement cachedStmt = jdbcPooledConnection.getCachedStatement(cacheKey);
if (cachedStmt == null) {
PreparedStatement stmt = delegate.prepareStatement(sql);
cachedStmt = jdbcPooledConnection.putCachedStatement(cacheKey, stmt);
}
return JdbcProxyFactory.INSTANCE.getProxyPreparedStatement(jdbcPooledConnection, cachedStmt, cacheKey);
}
else {
This way, the LruStatementCache contains delegates instead of proxies, which also means that the LruEvictionListener will close delegates - thus fixing my memory leak.
It also means that JdbcProxyTest.testCachePrepared() now breaks because the prepareStatement() methods now return different proxies for the same delegate. I.e. this fails:
PreparedStatement prepareStatement1 = connection.prepareStatement("SELECT 1 FROM nothing WHERE a=? AND b=? AND c=? AND d=?");
PreparedStatement prepareStatement2 = connection.prepareStatement("SELECT 1 FROM nothing WHERE a=? AND b=? AND c=? AND d=?");
Assert.assertEquals(prepareStatement1, prepareStatement2);
Can you tell me what the "crucial semantics" of the LruStatementCache are please? The properties / assumptions that must not be broken at any cost? I am already concerned that the cache hands out the same PreparedStatement simultaneously to two different callers - regardless of whether or not it has been proxied.
Cheers,
Chris
from btm.
Actually, it looks like putCachedStatement() can return "null" under some conditions. So this is probably better:
if (useStatementCache) {
CacheKey cacheKey = new CacheKey(sql, columnNames);
PreparedStatement cachedStmt = jdbcPooledConnection.getCachedStatement(cacheKey);
if (cachedStmt == null) {
cachedStmt = delegate.prepareStatement(sql, columnNames);
jdbcPooledConnection.putCachedStatement(cacheKey, cachedStmt);
}
return JdbcProxyFactory.INSTANCE.getProxyPreparedStatement(jdbcPooledConnection, cachedStmt, cacheKey);
}
else {
from btm.
This fix is going to require moving to JDK6, so that I can use isWrapperFor() and unwrap() to examine the underlying delegate objects. According to issue #17, this should be OK.
from btm.
Has then been addressed in your recent pull requests or is this outstanding?
from btm.
The points that I raised in the original comment have all been addressed. However, I have lingering concerns over the way that the cache allows a PreparedStatement to be "used" by more than one caller at a time. I just don't see how that can work. Fortunately, a connection is typically used by a single thread at a time, which makes my Doomsday Scenario much less likely.
from btm.
It should not be possible for more than one thread to access a JdbcPooledConnection (and therefore PreparedStatement) at one time, unless somewhere else we are violating the JTA spec.
from btm.
True, so the only scenario where the cache could cause problems is when someone does the following within a single thread:
String sql = "SELECT * FROM table WHERE ...";
PreparedStatement stmt1 = connection.prepareStatement(sql);
... // no-one closes stmt1
PreparedStatement stmt2 = connection.prepareStatement(sql);
At the moment, stmt1 and stmt2 would be proxy wrappers around the same underlying statement delegate. I don't believe that the statement cache should ever permit this to happen - if a statement delegate is in use then we should probably create a brand new and uncached PreparedStatement for the query instead.
So basically:
- the statement's usageCount would become a boolean instead of an int,
- PreparedStatementJavaProxy.close() would become able to close a delegate that threw an SQLException and then remove it from the cache, without needing to worry about side-effects.
from btm.
Related Issues (20)
- MySQL 8 support HOT 1
- How to configure log4j debug logs for bitrnix
- XAFactories which implement java.util.Map (MQXAConnectionFactory) cannot be initialized properly HOT 3
- Why is there no activity on the Bitronix github? HOT 2
- Using bitronox manager, XA not working with my custom dev-kit adapter HOT 7
- Transaction Manager problem HOT 1
- Glad to see the BTM project active again
- searching best solution for error handling HOT 1
- Error show in tomcat logs HOT 2
- Connection pool unable to recover after database connectivity loss HOT 1
- Question on rollback HOT 1
- Clarify requirements for XAResourceProducer unique name HOT 3
- Support custom XAResourceProducer implementations in ResourceLoader HOT 1
- Transaction Timeout Not working HOT 1
- Using ActiveMQ and bitronix-transaction-manager redelivery issue HOT 1
- Data Security Issue : Vendor property password is getting logged without masking HOT 1
- XA making multiple connections with MQ manager HOT 3
- Is it possible to recover heuristic exception.
- Is it possible to release 3.x?
- Issues related to spring cloud + feign HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from btm.