Re: One question about setting query timeout.

From: zhangyuanchao <zhangyuanchao(at)highgo(dot)com(dot)cn>
To: Dave Cramer <pg(at)fastcrypt(dot)com>
Cc: List <pgsql-jdbc(at)postgresql(dot)org>
Subject: Re: One question about setting query timeout.
Date: 2014-02-18 08:30:07
Message-ID: 53031A0F.6040402@highgo.com.cn
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-jdbc

On 02/17/2014 09:08 PM, Dave Cramer wrote:
> Hi,
>
> There were some fixes put into the latest version can you check out
> the snapshot here ?
>
> https://oss.sonatype.org/content/repositories/snapshots/org/postgresql/postgresql/
>
> Dave Cramer
>
> dave.cramer(at)credativ(dot)ca
> http://www.credativ.ca
>
>
> On Tue, Feb 11, 2014 at 2:01 AM, zhangyuanchao
> <zhangyuanchao(at)highgo(dot)com(dot)cn <mailto:zhangyuanchao(at)highgo(dot)com(dot)cn>> wrote:
>
> On 02/10/2014 07:18 PM, Dave Cramer wrote:
>> I think this is a known issues. What version of the driver are
>> you using ?
>>
>> Dave Cramer
>>
>> dave.cramer(at)credativ(dot)ca
>> http://www.credativ.ca
>>
>>
>> On Sun, Feb 9, 2014 at 10:46 PM, zhangyuanchao
>> <zhangyuanchao(at)highgo(dot)com(dot)cn
>> <mailto:zhangyuanchao(at)highgo(dot)com(dot)cn>> wrote:
>>
>> Hi,
>> I have a question about setting query timeout by jdbc.
>> When tested my application with Tomcat7.0 and loadrunner,my
>> tomcat's configure file is like this:
>> <Resource ......
>> jdbcInterceptors="QueryTimeoutInterceptor(queryTimeout=600)"
>> ....../>.
>> After setting like above ,tomcat will call the jdbc's
>> setQueryTimeout function and set the query timeout to
>> 600seconds for each statement.
>> Next,i start my test with 150 concurrency.After about 10
>> minutes later,i found the response time was much longer than
>> before.At that moment,i found there were a lot of statement
>> object in the heap memory of the JVM.And the JVM's gc could
>> not clean these objects,because they were referenced by the
>> TimerTask.So i read the source code of the jdbc and Timer
>> class,i found the mainloop function of the Timer calss can
>> cause the problem.This is the code of mainloop function in
>> Timer class and i think the red colour text is that what
>> cause the problem:
>>
>> private void mainLoop() {
>> while (true) {
>> try {
>> TimerTask task;
>> boolean taskFired;
>> synchronized(queue) {
>> // Wait for queue to become non-empty
>> while (queue.isEmpty() && newTasksMayBeScheduled)
>> queue.wait();
>> if (queue.isEmpty())
>> break; // Queue is empty and will forever remain; die
>>
>> // Queue nonempty; look at first evt and do the right thing
>> long currentTime, executionTime;
>> task = queue.getMin();fixes
>> synchronized(task.lock) {
>> if (task.state == TimerTask.CANCELLED) {
>> queue.removeMin();
>> continue; // No action required, poll queue again
>> }
>> currentTime = System.currentTimeMillis();
>> executionTime = task.nextExecutionTime;
>> if (taskFired = (executionTime<=currentTime)) {
>> if (task.period == 0) { // Non-repeating, remove
>> queue.removeMin();
>> task.state = TimerTask.EXECUTED;
>> } else { // Repeating task, reschedule
>> queue.rescheduleMin(
>> task.period<0 ? currentTime - task.period
>> : executionTime + task.period);
>> }
>> }
>> }
>> if (!taskFired) // Task hasn't yet fired; wait
>> queue.wait(executionTime - currentTime);
>> }
>> if (taskFired) // Task fired; run it, holding no locks
>> task.run();
>> } catch(InterruptedException e) {
>> }
>> }
>> }
>> }
>> So,i want to ask if there is any solution for this problem.
>> Thanks very much.
>>
>>
>>
> Hi Dave,
> Thanks for your response.
> The version of driver that i am using is 9.3-1100(the latest
> version).And i searched some similar problem in the mail list,but
> i did not get it.I think the reason is : when an statement has
> been execute finished successfully and the statement cancel the
> timertask,but the timertask is still in Timer's queue.So the
> statement is always referenced by the Timer class and it can not
> be cleaned.
> Let me look at the mainloop function of Timer class.The part that
> is marked red colour can cause the mainloop stop,so the canceled
> timetask can not be removed from the queue.If i set the query
> timeout to 600 seconds,the mainloop will wait for about ten
> minutes.In the ten minutes,there will be more an more statement in
> the JVM heap.
> I think this is what cause the problem,but i don't have some good
> idea to solve it.Do you have some solution?Thanks a lot.
>
>
Hi,
I checked out the snapshot you sent to me.And i download this
https://oss.sonatype.org/content/repositories/snapshots/org/postgresql/postgresql/9.3-1101-jdbc4-SNAPSHOT/postgresql-9.3-1101-jdbc4-20140214.105528-4.jar
and test my application , i got the same problem.I look at the fixes
that was put into the latest version,i think that can not solve my
issue.I think you may not understand my question.
I have a solution like this,
adding a function into Driver.java.in:
public static Timer getCancelTimer()
{
return cancelTimer;
}
and modifing the killTimer() function AbstractJdbc2Statement.java:
private synchronized void killTimer()
{
if ( cancelTimer != null )
{
cancelTimer.cancel();
Driver.getCancelTimer().purge();
cancelTimer = null;
}

}
After modifing like above, i solved the problem.But i don't know if the
solution is good.
Thank you.

In response to

Responses

Browse pgsql-jdbc by date

  From Date Subject
Next Message Dave Cramer 2014-02-18 12:00:28 Re: One question about setting query timeout.
Previous Message Dave Cramer 2014-02-17 13:08:12 Re: One question about setting query timeout.