当前位置: 首页 > 面试题库 >

如何在JPA EntityManager查询上设置超时期限

钱锐
2023-03-14
问题内容

我目前从EntityManager查询中收到连接超时错误。是否可以为这些设置超时?

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="CallPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>call.structure.Task</class>
    <class>call.structure.Installation</class>
    <class>call.structure.Contents</class>
    <class>call.structure.Recipient</class>
    <class>call.structure.CallTask</class>
    <class>call.structure.SmsTask</class>
    <class>call.structure.EmailTask</class>
    <class>call.security.User</class>
    <class>call.structure.content.Content</class>
    <class>call.structure.content.RecordContent</class>
    <class>call.structure.content.WaitContent</class>
    <class>call.structure.content.TextContent</class>
    <class>call.structure.content.VariableContent</class>
    <class>call.structure.content.SoundContent</class>
    <class>call.structure.content.SubjectContent</class>
    <class>call.structure.content.FileContent</class>
    <class>call.structure.Bounce</class>
    <properties>
      <property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@127.0.0.1:1521:TEST"/>
      <property name="javax.persistence.jdbc.password" value="userpassword"/>
      <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
      <property name="javax.persistence.jdbc.user" value="username"/>
    </properties>
   </persistence-unit>
</persistence>

代码在我的线程的运行功能中超时:

private class TaskDB extends Thread {

    private final long WAITING_TIME = 20000L;

    @Override
    public void run() {

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

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

                Set<SmsTask> normalClone = new HashSet<SmsTask>(normal);
                // Abort task in futur.
                List<SmsTask> taskToRemove = new ArrayList<SmsTask>();
                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<SmsTask>) 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<SmsTask> taskResults = (List<SmsTask>) 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
[...]

问题答案:

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

可移植应用程序不应依赖此提示。根据使用的持久性提供程序和数据库,可能会或可能不会观察到提示。

可以将所有查询的默认值(以毫秒为单位)设置为persistence.xml:

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

通过持久性创建EntityManagerFactory时,也可以赋予相同的属性。createEntityManagerFactory。

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

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

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



 类似资料:
  • 我正在使用Spring框架。使用NamedParameterJdbcTemplate时,如何设置查询超时?我注意到JdbcTemplate有一个setQueryTimeout(int queryTimeout)方法,但我还没有找到一种使用NamedParameterJdbcTemplate实现这一点的方法。它有一个getJdbcOperations()方法,但似乎没有公开setQueryTimeo

  • 问题内容: 在我的Web应用程序中,一些postgres sql查询需要一些时间才能执行。我只想为其中一部分设置语句超时。 查询的一部分必须通过超时取消,但是其他部分必须可以不受任何限制地工作。 在postgres中存在statement_timeout函数。 如何使用statement_timeout函数包装SqlAlchemy查询? 像这样: 对我来说,设置超时的最佳方法是这样的: SqlAl

  • 如何在应用程序级别配置默认查询超时。我使用spring、hibernate和db2作为后端。在datasource级别设置超时不是一个选项,因为我们使用的是旧版本的IBM WebSphere。我尝试在事务管理器中配置defaultTimeout,但这没有帮助。我也不想集成c3p0连接池。hibernate是否为在应用程序级别设置全局查询超时提供了其他选项,如果是,如何配置。

  • 问题内容: 我知道您可以设置用户个人资料或设置查询的一般超时时间。 但是我希望对过程中的特定查询设置超时并捕获异常,例如: 这可能吗?我可以捕获所有超时异常吗?每个块或查询?找不到有关该主题的太多信息。 问题答案: 不,您不能在pl / sql中设置超时。为此,您可以使用宿主语言来嵌入sql和pl / sql。

  • 我在我的项目中设置了一个RestTemplate和一个AsyncRestTemplate,如下所示: 我注意到连接超时实际上并不起作用,除非我将httpRequestFactory()bean更改为如下所示: 如果我将DEFAULT_READ_TIMEOUT_MILLISECONDS设置为5,则当我使用restTemplate时会发生超时(正如预期的那样)。但是,当我使用AsyncRestTemp

  • 问题内容: 如何为此操作创建超时:? 问题答案: 我相信正确的方法将是这样的: 当然,这是我使用Oracle的地方,但是我希望这可以给您一个想法。