https://issues.apache.org/bugzilla/show_bug.cgi?id=53995
Priority: P2
Bug ID: 53995
Keywords: PatchAvailable
Assignee: [email protected]
Summary: AbstractJDBCTestElement shares PreparedStatement
between multi-threads
Severity: critical
Classification: Unclassified
OS: Linux
Reporter: [email protected]
Hardware: PC
Status: NEW
Version: 2.7
Component: Main
Product: JMeter
Created attachment 29468
--> https://issues.apache.org/bugzilla/attachment.cgi?id=29468&action=edit
The patch for JMeter 2.7-rc3, fix the shared PreparedStatement bug.
The implementation of AbstractJDBCTestElement uses a map to cache the
PreparedStatement for each Connection, and shares that cache between
multi-threads, which is the cause of the bug.
According to the section 13.1.4 of JDBC 4.0 specification
(http://jcp.org/aboutJava/communityprocess/final/jsr221/index.html),
> 13.1.4 Closing Statement Objects
> An application calls the method Statement.close to indicate that it
> has finished processing a statement. All Statement objects will be closed
> when the con- nection that created them is closed. However, it is good coding
> practice for applications to close statements as soon as they have finished
> processing them. This allows any external resources that the statement is
> using to be released immediately.
> Closing a Statement object will close and invalidate any instances of
> ResultSet produced by that Statement object. The resources held by the
> ResultSet object may not be released until garbage collection runs again,
> so it is a good practice to explicitly close ResultSet objects when they
> are no longer needed.
> Once a Statement has been closed, any attempt to access any of its methods
> with the exception of the isClosed or close methods will result in a
> SQLException being thrown.
> These comments about closing Statement objects apply to PreparedStatement
> and CallableStatement objects as well.
It's clear that closing a PreparedStatement object will automatically close all
the ResultSet objects opened by it. Therefore, if a PreparedStatement is shared
between thread A and thread B, and the thread A is closing the
PreparedStatement object while thread B is still in use of a ResultSet object
opened by that PreparedStatement object, the ResultSet object will be closed
indirectly by thread A without notifying thread B. This situation could happen,
since the cache of PreparedStatement has a capacity limit and it will
automatically close an old cached PreparedStatement object while adding a new
PreparedStatement to the cache reaching the capacity limit.
It's also easy to reproduce the bug: create a JDBC testing plan using a
prepread statement, with 300 threads and 2000 loops; then run the test, the bug
*may* occur. If the bug does not occur, try to increase the number of threads
and the number of loops. The log of the JDBC driver shows that it is caused by
using a closed ResultSet object.
The attachment is the patch for Apache JMeter v2.7-rc3.
The patch does the following works:
1. change the cache of PreparedStatement in AbstractJDBCTestElement to a thread
local cache;
2. add some logging statements in order to help locating the bug;
3. fix the location of "jcharts" component in the "build.properties"
configuration file, since the "www.mvnsearch.org" was moved.
--
You are receiving this mail because:
You are the assignee for the bug.