JPA query timeout parameters ignored but @Transaction annotation works

故事扮演 提交于 2020-01-03 17:17:04

问题


I want JPA queries made by my Spring Boot application to a Postgres database to timeout after 5 seconds.

I have created this 20 seconds query to test timeouts:

@Query(value = "select count(*) from pg_sleep(20)", nativeQuery = true)
int slowQuery();

I've set the following properties in application.config:

spring.jpa.properties.javax.persistence.query.timeout=3000
javax.persistence.query.timeout=5000

But the query does not timeout after 3s or 5s (it still takes 20s to execute).

Strangely, if I annotate slowQuery with @Transactional(timeout = 10), it times out after 10s or so.

I would prefer not to annotate every query. I'm using JPA 2.0 and the Tomcat connection pool.

What magic is required to make the timeout work just by setting them in application properties file?


回答1:


To make the timeout generic, in your JpaConfiguration, when you declare the PlatformTransactionManager Bean, you can set the default timeout of the transactions:

@Bean
public PlatformTransactionManager transactionManager() throws Exception {
    JpaTransactionManager txManager = new JpaTransactionManager();
    txManager.setEntityManagerFactory(entityManagerFactory().getObject());
    txManager.setDataSource(this.dataSource);
    txManager.setDefaultTimeout(10); //Put 10 seconds timeout
    return txManager;
}

PlatformTransactionManager inherits AbstractPlatformTransactionManager which contains that method:

    /**
     * Specify the default timeout that this transaction manager should apply
     * if there is no timeout specified at the transaction level, in seconds.
     * <p>Default is the underlying transaction infrastructure's default timeout,
     * e.g. typically 30 seconds in case of a JTA provider, indicated by the
     * {@code TransactionDefinition.TIMEOUT_DEFAULT} value.
     * @see org.springframework.transaction.TransactionDefinition#TIMEOUT_DEFAULT
     */
    public final void setDefaultTimeout(int defaultTimeout) {
        if (defaultTimeout < TransactionDefinition.TIMEOUT_DEFAULT) {
            throw new InvalidTimeoutException("Invalid default timeout", defaultTimeout);
        }
        this.defaultTimeout = defaultTimeout;
    }


来源:https://stackoverflow.com/questions/53827071/jpa-query-timeout-parameters-ignored-but-transaction-annotation-works

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!