在EntityManager查询上设置超时

 HGKHGK 发布于 2023-01-09 08:38

我目前正从EntityManager查询中获取连接超时错误.是否可以为这些设置超时?

persistence.xml中



  
    org.eclipse.persistence.jpa.PersistenceProvider
    call.structure.Task
    call.structure.Installation
    call.structure.Contents
    call.structure.Recipient
    call.structure.CallTask
    call.structure.SmsTask
    call.structure.EmailTask
    call.security.User
    call.structure.content.Content
    call.structure.content.RecordContent
    call.structure.content.WaitContent
    call.structure.content.TextContent
    call.structure.content.VariableContent
    call.structure.content.SoundContent
    call.structure.content.SubjectContent
    call.structure.content.FileContent
    call.structure.Bounce
    
      
      
      
      
    
   

代码在我的线程的run函数中超时:

private class TaskDB extends Thread {

    private final long WAITING_TIME = 20000L;

    @Override
    public void run() {

        Set remove = SMSManager.this.getRemoveTask();
        Set normal = SMSManager.this.getNormalTask();

        try {
            while(true){
                EntityManager em = DB.getEM();  //Calls EntityManagerFactory.createEntityManager()
                em.getTransaction().begin();

                Set normalClone = new HashSet(normal);
                // Abort task in futur.
                List taskToRemove = new ArrayList();
                if (!remove.isEmpty()) {

                    String queryString = "SELECT t FROM SmsTask t WHERE t.id IN :remove ";
                    if (!normalClone.isEmpty())
                        queryString += "AND t.id NOT IN :normal ";

                    Query query = em.createQuery(queryString);
                    query.setParameter("remove", Utils.taskToIdList(remove));
                    if (!normalClone.isEmpty())
                        query.setParameter("normal", Utils.taskToIdList(normalClone));

                    taskToRemove = (List) query.getResultList();
                    for (SmsTask task : taskToRemove) {
                        removedTask.add(task);
                        remove.remove(task);
                    }
                }

                String queryString = "SELECT t FROM SmsTask t WHERE (t.scheduleTime IS NULL OR t.scheduleTime < :dateNow) AND t.status = co.dium.call.structure.Task.StatusTask.NOT_START ";
                if (!taskToRemove.isEmpty())
                    queryString += "AND t.id NOT IN :toRemove ";

                Query query = em.createQuery(queryString);
                query.setParameter("dateNow", Utils.obtainUniversalTime());
                if (!taskToRemove.isEmpty())
                    query.setParameter("toRemove", Utils.taskToIdList(taskToRemove));
                List taskResults = (List) query.getResultList();

                em.getTransaction().commit();

                for (SmsTask task : taskResults) 
                    addTask(task);

                SMSManager.TaskRemove.sleep(WAITING_TIME);
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(SMSManager.class.getName()).log(Level.SEVERE, null, ex);
        }

        System.out.println("Thread interrompu !");
        Thread.currentThread().interrupt();
    }
}

我得到的超时错误:

org.clipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLRecoverableException: I/O error: Socket read timed out
Error Code: 17002
Call: [....sql query...]
[...]
at org.eclipse.persistence.internal.EJBQueryImpl.getResultList(EJBQueryImpl.java:742)
at call.manager.sms.SMSManager$TaskDB.run(SMSManager.java:367)
Caused by: java.sql.SQLRecoverableException: I/O Error: Scoket read timed out
[...]

Mikko Maunu.. 19

是的,有javax.persistence.query.timeout.根据JPA 2.0规范支持此查询提示是可选的:

便携式应用程序不应该依赖这个提示.根据使用的持久性提供程序和数据库,可能会也可能不会显示提示.

对于所有查询,可以将缺省值(以毫秒为单位)设置为persistence.xml:


通过Persistence创建EntityManagerFactory时也可以给出相同的属性.createEntityManagerFactory.

它也可以为每个查询覆盖/设置:

query.setHint("javax.persistence.query.timeout", 2000);

可以通过NamedQuery中的属性提示获得相同的功能.

1 个回答
  • 是的,有javax.persistence.query.timeout.根据JPA 2.0规范支持此查询提示是可选的:

    便携式应用程序不应该依赖这个提示.根据使用的持久性提供程序和数据库,可能会也可能不会显示提示.

    对于所有查询,可以将缺省值(以毫秒为单位)设置为persistence.xml:

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

    通过Persistence创建EntityManagerFactory时也可以给出相同的属性.createEntityManagerFactory.

    它也可以为每个查询覆盖/设置:

    query.setHint("javax.persistence.query.timeout", 2000);
    

    可以通过NamedQuery中的属性提示获得相同的功能.

    2023-01-09 08:44 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有