当前位置: 首页 > 知识库问答 >
问题:

Postgres JDBC线程卡在java上。网SocketInputStream。socketRead0,即使已定义超时

冯枫
2023-03-14

我们在Wildfly 16上使用Java应用程序,该应用程序使用Eclipse Link与Postgres 9.4数据库连接。应用程序服务器配置为使用连池。该应用程序在夜间将项目索引到Solr实例,有时我们会遇到阻塞线程的问题。似乎数据库查询终究没有返回。我们在持久性单元中设置了查询超时,这似乎不起作用。我们在persistence.xml中添加了以下条目:

<property name="javax.persistence.query.timeout" value="30000"/>

该系统使用Java 11 jre。我们正在使用docker wildfly图像(https://hub.docker.com/r/jboss/wildfly/dockerfile)但我们也看到了其他应用服务器和Java版本的问题。

线程转储显示了一些细节。该进程正在运行数小时。我们预计30秒后会抛出异常。我们错过了什么?

"Indexer thread" #181 daemon prio=5 os_prio=0 cpu=3845600.45ms elapsed=124856.57s tid=0x000000000a51b800 nid=0x12d runnable  [0x00007fb51dcb9000]
   java.lang.Thread.State: RUNNABLE
        at java.net.SocketInputStream.socketRead0(java.base@11.0.4/Native Method)
        at java.net.SocketInputStream.socketRead(java.base@11.0.4/SocketInputStream.java:115)
        at java.net.SocketInputStream.read(java.base@11.0.4/SocketInputStream.java:168)
        at java.net.SocketInputStream.read(java.base@11.0.4/SocketInputStream.java:140)
        at org.postgresql.core.VisibleBufferedInputStream.readMore(VisibleBufferedInputStream.java:146)
        at org.postgresql.core.VisibleBufferedInputStream.ensureBytes(VisibleBufferedInputStream.java:115)
        at org.postgresql.core.VisibleBufferedInputStream.read(VisibleBufferedInputStream.java:71)
        at org.postgresql.core.PGStream.ReceiveChar(PGStream.java:283)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1719)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:173)
        - locked  (a org.postgresql.core.v3.QueryExecutorImpl)
        at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:622)
        at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:472)
        at org.postgresql.jdbc.PgStatement.executeUpdate(PgStatement.java:429)
        at jdk.internal.reflect.GeneratedMethodAccessor24.invoke(Unknown Source)
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@11.0.4/DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(java.base@11.0.4/Method.java:566)
        at org.postgresql.ds.PGPooledConnection$StatementHandler.invoke(PGPooledConnection.java:466)
        at com.sun.proxy.$Proxy69.executeUpdate(Unknown Source)
        at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.executeUpdate(WrappedPreparedStatement.java:537)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:898)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:970)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:640)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:567)
        at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:2096)
        at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:311)
        at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:275)
        at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:261)
        at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.updateObject(DatasourceCallQueryMechanism.java:832)
        at org.eclipse.persistence.internal.queries.StatementQueryMechanism.updateObject(StatementQueryMechanism.java:437)
        at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.updateObjectForWriteWithChangeSet(DatabaseQueryMechanism.java:1093)
        at org.eclipse.persistence.queries.UpdateObjectQuery.executeCommitWithChangeSet(UpdateObjectQuery.java:86)
        at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:316)
        at org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:60)
        at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:914)
        at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:813)
        at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:110)
        at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:87)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2981)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1895)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1877)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1827)
        at org.eclipse.persistence.internal.sessions.CommitManager.commitChangedObjectsForClassWithChangeSet(CommitManager.java:275)
        at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:133)
        at org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:4387)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1493)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1583)
        at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:280)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1220)
        at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:136)
        at com.freiheit.vrms.persistence.SystemObjectPersistenceService.createOrUpdateNextIndexerRun(SystemObjectPersistenceService.java:2134)
        at com.freiheit.vrms.service.search.SearchService.attributeIndexFields(SearchService.java:322)
        at com.freiheit.vrms.service.search.SearchService.indexObjectInternal(SearchService.java:848)
        at com.freiheit.vrms.service.search.SearchService.indexObjectInForeground(SearchService.java:752)
        - locked  (a java.lang.Object)
        at com.freiheit.vrms.service.search.SearchService.indexObjectInForeground(SearchService.java:746)
        at com.freiheit.vrms.service.search.IndexJob$JobType$2.execute(IndexJob.java:60)
        at com.freiheit.vrms.service.search.IndexJob.execute(IndexJob.java:104)
        at com.freiheit.vrms.service.search.IndexQueue.handleMessage(IndexQueue.java:243)
        at com.freiheit.vrms.service.search.IndexQueue.run(IndexQueue.java:155)
        at java.lang.Thread.run(java.base@11.0.4/Thread.java:834)

   Locked ownable synchronizers:
        -  (a java.util.concurrent.locks.ReentrantLock$FairSync)

编辑:我想添加一些额外的代码,这会导致线程冻结。

final EntityTransaction transaction = em.getTransaction();
transaction.begin();
updateNextIndexerRun( em, id, nextIndexerRun );
transaction.commit();

如上图所示,线程卡在transaction.commit()行。这个片段每天被调用数千次,并且大部分时间都不会造成任何麻烦。将持久化数据的表一次有大约20000个条目。方法updateNextIndree Run是这样html" target="_blank">定义的:

private void updateNextIndexerRun( final EntityManager em, final Long id, @Nullable final Calendar newNextIndexerRun ) {

    final NextIndexerRunDBBean oldNextIndexerRun = getNextIndexerRun( em, id );

    if ( newNextIndexerRun == null && oldNextIndexerRun != null ) {
        em.remove( oldNextIndexerRun );
    } else if ( newNextIndexerRun != null ) {
        if ( oldNextIndexerRun == null ) {
            em.persist( new NextIndexerRunDBBean( id, newNextIndexerRun ) );
        } else {
            em.merge( new NextIndexerRunDBBean( id, newNextIndexerRun ) );
        }
    }
}

共有1个答案

相温文
2023-03-14

查询本身在30秒内运行,因此没有应用超时。现在我们从这里看到

上面的JPQL查询将在50毫秒后超时,除非在超时阈值之前获取结果集。

您已经在读取结果集,但它要么太大,要么读取速度不够快。

 类似资料:
  • 我有一个Java应用程序,它运行一系列并行线程,从AmazonS3下载对象块。我注意到,在没有任何问题的情况下运行了几个小时后,最终得到一个特定的块将挂起并导致程序冻结。 Java进程仍在运行,但CPU占用和网络IO很少。执行线程转储时,有一个线程永远不会离开IN_NATIVE状态,在SSL握手过程中,ocketRead0()似乎永远不会返回。下面是转述的堆栈跟踪: 下面是如何执行的代码片段: 作

  • 问题内容: 想在一个固定的时间内运行一个线程。如果未在该时间内完成,我想杀死它,抛出一些异常或以某种方式处理它。怎么做到呢? 我从该线程 了解到的一种方法是在该线程的run()方法内使用TimerTask。 有没有更好的解决方案呢? 编辑:添加赏金,因为我需要一个更明确的答案。下面给出的ExecutorService代码无法解决我的问题。为什么在执行完某些代码后就进入sleep()-我无法处理这段

  • 问题内容: 我希望在下面的代码中调用newTarget.a()和newTarget.b()时应用调制后的ASM类,以便它看起来像这样 当调用应用了修改的ASM类的newTarget.a()和newTarget.b()时,如何获得以下结果? 码: 想要结果: 第一种方法 第二种方法 转换方法 第一种方法 转换方法 第二种方法 问题答案: 您正在寻找Java API 。它要求您通过参数附加Java代理

  • 问题内容: 我的一项活动遇到了一个奇怪的问题。从拍照/录像回来时,我正在显示一个对话框,允许用户命名相机。用户按下“确定”后,我将使用所请求的文件名发送给主题,该主题将复制文件(并显示进度对话框)。 由于某种原因,即使我调用,总是在主线程上调用执行复制的函数。 更改呼叫以解决问题。我还是想知道为什么它不起作用… 问题答案: 并且是那里最混乱的运营商。前者确保订阅副作用在指定的调度程序(线程)上发生

  • 有人知道我如何让一个Java程序在网页上运行吗?我知道现在很多浏览器不支持Java的安全风险,但说我使用的是老版本的Java,如Java 6。 我必须做什么才能使它在网页上运行?当然,当用户点击按钮时,说“允许”或“运行程序”是正确的。我不能为此使用Javascript。 谢谢

  • 我尝试在我的linux服务器上安装java HTTP API。我尝试从命令pompt执行此命令以运行服务: 那么我有一个错误: 线程“main”java中出现异常。网BindException:地址已在sun上使用。尼奥。中国网。bind0(本机方法)在sun。尼奥。中国网。bind(Net.java:463)位于sun。尼奥。中国网。在sun上绑定(Net.java:455)。尼奥。总经理塞尔索