连接超时使用Executor Service

时间:2016-03-10 13:54:41

标签: java jpa playframework playframework-2.0

我有一个play 2.4应用程序,我已经设置了一个工具来运行这样的预定执行程序(在Global中):

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)

1 个答案:

答案 0 :(得分:0)

我会猜测这一个。

我认为当你使用你自己的线程时,你可以绕过由play管理的JPA上下文。

除了Job seems to be the preferred one之外,可能有几种方法可以绕过它。最后有一个计划作业的例子。

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

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

类似的stackoverflow问题