java thread在使用executorService执行oracle查询时挂起

时间:2013-03-05 09:40:19

标签: java multithreading oracle jdbc

"pool-11-thread-1" prio=10 tid=0x0a974c00 nid=0x7210 runnable [0x3f3ad000]
   java.lang.Thread.State: RUNNABLE
  at oracle.jdbc.driver.T2CStatement.t2cDefineExecuteFetch(Native Method)
  at oracle.jdbc.driver.T2CPreparedStatement.doDefineExecuteFetch(T2CPreparedStatement.java:878)
  at oracle.jdbc.driver.T2CPreparedStatement.executeForRows(T2CPreparedStatement.java:760)
  at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1062)
  at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1126)
  at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3339)
  at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3445)
  - locked <0x69579fb0> (a oracle.jdbc.driver.T2CPreparedStatement)
  - locked <0x66157d68> (a oracle.jdbc.driver.T2CConnection)
  at org.jboss.resource.adapter.jdbc.CachedPreparedStatement.execute(CachedPreparedStatement.java:216)
  at org.jboss.resource.adapter.jdbc.WrappedPreparedStatement.execute(WrappedPreparedStatement.java:209)
  at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.java:180)
  at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExecuteQuery(GeneralStatement.java:205)
  at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:173)
  at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForObject(GeneralStatement.java:104)
  at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:561)
  at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:536)
  at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSessionImpl.java:93)
  at org.springframework.orm.ibatis.SqlMapClientTemplate$1.doInSqlMapClient(SqlMapClientTemplate.java:273)
  at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:209)
  at org.springframework.orm.ibatis.SqlMapClientTemplate.queryForObject(SqlMapClientTemplate.java:271)
  at com.alipay.bipgw.common.dal.bankchannel.ibatis.IbatisBipBusiOrderDAO.queryOrderOutTime(IbatisBipBusiOrderDAO.java:319)
  at sun.reflect.GeneratedMethodAccessor3333.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  at java.lang.reflect.Method.invoke(Method.java:597)
  at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
  at com.alipay.bipgw.common.dal.monitor.DalMonitorInterceptor.invoke(DalMonitorInterceptor.java:60)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
  at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
  at $Proxy79.queryOrderOutTime(Unknown Source)
  at com.alipay.bipgw.prodcore.repository.impl.BusiOrderRepositoryImpl.queryOrderOutTime(BusiOrderRepositoryImpl.java:402)
  at com.alipay.bipgw.prodcore.listener.ProdStatusChangeTimeoutTaskListener.execute(ProdStatusChangeTimeoutTaskListener.java:148)
  at com.alipay.bipgw.prodcore.listener.ProdStatusChangeTimeoutTaskListener.access$000(ProdStatusChangeTimeoutTaskListener.java:60)
  at com.alipay.bipgw.prodcore.listener.ProdStatusChangeTimeoutTaskListener$1.run(ProdStatusChangeTimeoutTaskListener.java:104)
  at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
  at java.lang.Thread.run(Thread.java:662)
像这样的java程序:

public void onUniformEvent(UniformEvent message, UniformEventContext uContext) {
    try {
        // single thread running
        service.execute(new Runnable() {
            public void run() {
                try{
                    execute();
                }catch(Exception e ){
                    logger.error("working error",e);
                }

            }
        });
    } catch (RejectedExecutionException e) {
        logger.error("ProdStatusChangeTimeoutTaskListener:error", e);
    } catch (Exception e) {
        logger.error("ProdStatusChangeTimeoutTaskListener:error", e);
    }

}
 //omit the body
 private void execute() {.....}

并且execute方法不会启动任何线程。

在两天内我转储了几个线程转储 2013-03-04 16:54:12

- locked <0x695f91f0> (a oracle.jdbc.driver.T2CPreparedStatement)
- locked <0x6615a2d0> (a oracle.jdbc.driver.T2CConnection)  

2013-03-04 17:20:53

- locked <0x695f91f0> (a oracle.jdbc.driver.T2CPreparedStatement)
- locked <0x6615a2d0> (a oracle.jdbc.driver.T2CConnection)

2013-03-05 10:58:30

- locked <0x6957bec8> (a oracle.jdbc.driver.T2CPreparedStatement)
- locked <0x66157e90> (a oracle.jdbc.driver.T2CConnection)

2013-03-05 17:16:31

- locked <0x69579fb0> (a oracle.jdbc.driver.T2CPreparedStatement)
- locked <0x66157d68> (a oracle.jdbc.driver.T2CConnection)
似乎jdbc客户端的锁保持已经改变了,但前两个在2013-03-04 16:54:12和2013-03-04 17:20:53,它们是相同的

我正在使用Excutors.newSingleThreadExecutor()在backgroud中执行查询作业,并且以下任务将在20分钟间隔内提交给此执行程序服务,但工作线程似乎在执行查询时挂起,因此以下任务不会被执行。它持续了好几天,没有异常发生,根本没有日志输出,有人可以帮助我吗?感谢

2 个答案:

答案 0 :(得分:0)

问题可能在于您的实际查询 - 这是一项长期运行的任务吗?你知道完成它需要多长时间吗?

可能(但这取决于查询本身)先前的查询是锁定表,而后者又会阻塞表。

我要做的第一件事是验证查询是否确实在20分钟内完成,并且一直这样做。在您知道它之后,您可以调查您所看到的悬挂行为的其他可能原因。

当查询运行时,我还建议您检查查询的解释计划(看看它在做什么 - 最多花些时间等等)。我还要检查相关的统计数据是否是最新的(可能不是新版Oracle的问题)

答案 1 :(得分:0)

这个问题已经解决了〜 在几次实时执行之后,输出dba监视数据库服务器端,并发现查询时间是210s,这超过了查询输出时间(180s),但是stamentent的取消请求可能无效并且数据库服务器可能没有回应那个请求。所以对原始查询进行处理的线程会挂起。类似的情况见[当我在JDBC应用程序中调用PreparedStatement.cancel()时,它是否真的在Oracle数据库中将其删除?

解决方案可以通过以下方式完成: 将sqlprofile添加到目标表,并使用跳过扫描生成sql以缩短查询时间。

但悬挂发生的最深层原因尚不清楚。