【问题标题】:Connection timeout Play JPA using Executor Service连接超时使用 Executor Service 播放 JPA
【发布时间】:2016-03-10 13:54:41
【问题描述】:

我有一个 play 2.4 应用程序,并且我已经设置了一个工具,可以像这样(在全局中)在预定的执行程序中运行:

ScheduledExecutorService scheduler =   Executors.newScheduledThreadPool(2);
Bot myBot = new Bot();
ScheduledFuture<?> sched =  scheduler.scheduleAtFixedRate(myBot, 2, 1, TimeUnit.MINUTES);

最终它会调用 DAO 来获取一些数据,看看它正在做的工作是否重复:

try{
            results = JPA.withTransaction(() -> {

                String queryStr = "select id from BotSearch bs "
                             + "where bs.headerText=:headerText";

                Query query = JPA.em().createQuery(queryStr);
                query.setParameter("headerText", title);

                return query.getResultList();
            }

        );  


        }catch(Throwable t){
            Logger.error("Failed to issue bot query ",t);
            t.printStackTrace();
        }

当它每次调用时,连接都会超时。我可以在应用程序的其他部分和其他数据库调用中进行该数据库调用,并且它们每次都成功。

实体管理器是否存在线程本地问题,会阻止它作为计划任务的一部分进行调用?或者还有其他可能导致此问题的原因吗?它只会在计划任务内失败。

例外是:

Caused by: java.sql.SQLTimeoutException: Timeout after 30028ms of waiting for a connection.
    at com.zaxxer.hikari.pool.BaseHikariPool.getConnection(BaseHikariPool.java:227) ~[HikariCP-2.3.7.jar:na]
    at com.zaxxer.hikari.pool.BaseHikariPool.getConnection(BaseHikariPool.java:182) ~[HikariCP-2.3.7.jar:na]
    at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:93) ~[HikariCP-2.3.7.jar:na]
    at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:139) ~[hibernate-core-4.3.9.Final.jar:4.3.9.Final]
    at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:380) ~[hibernate-core-4.3.9.Final.jar:4.3.9.Final]
    at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:228) ~[hibernate-core-4.3.9.Final.jar:4.3.9.Final]
    at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:171) ~[hibernate-core-4.3.9.Final.jar:4.3.9.Final]
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:67) ~[hibernate-core-4.3.9.Final.jar:4.3.9.Final]
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:162) ~[hibernate-core-4.3.9.Final.jar:4.3.9.Final]
    at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1471) ~[hibernate-core-4.3.9.Final.jar:4.3.9.Final]
javax.persistence.QueryTimeoutException: Could not open connection
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1725)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:1771)
    at org.hibernate.jpa.internal.TransactionImpl.begin(TransactionImpl.java:64)
    at play.db.jpa.DefaultJPAApi.withTransaction(DefaultJPAApi.java:133)
    at play.db.jpa.DefaultJPAApi.withTransaction(DefaultJPAApi.java:80)
    at play.db.jpa.JPA.withTransaction(JPA.java:127)
    at com.myproject.dao.BotSearchDAO.isDup(BotSearchDAO.java:34)
    at com.myproject.bots.alert.Bot.run(WSJBot.java:131)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

【问题讨论】:

  • 您能在使用callable/runable 的地方显示您的代码吗?
  • @Patrick 很高兴提供更多信息,但不确定您在寻找什么。上面的代码是它被调度的地方,并且 DB 调用在任务的 run() 方法中运行。
  • 我一直在寻找您收到线程结果的位置。类似sched.get()
  • @Patrick 该线程不返回任何内容。它醒来,做一些工作,并尝试做一些数据库操作。上面的 db 代码是它找到一些数据后所做的第二件事。
  • 好的。要指出问题是否与线程或 jpa/enitiy 管理器有关,您能否展示您的 Bot.class。我想有可运行的实现。

标签: java jpa playframework playframework-2.0


【解决方案1】:

我将对此进行猜测。

我认为这与您使用自己的线程时绕过由 play 管理的 JPA 上下文有关。

除了Job seems to be the preferred one,可能有几种方法可以绕过它。最后有一个Scheduled Jobs的例子。

还有JPAPlugin 强制初始化JPA 上下文并启动事务。

JPAPlugin.startTx(false);
// Do your stuff
JPAPlugin.endTx(false);

类似的stackoverflow问题

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-22
    • 2012-08-26
    • 1970-01-01
    • 1970-01-01
    • 2015-04-14
    • 2015-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多