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?
The timeout value is defined in milliseconds, so the JPQL query above will time out after 50 milliseconds unless the result set is being fetched prior to the timeout threshold. Hibernate also provides the org.hibernate.timeout query hint, which unlike its JPA counterpart, takes the timeout interval in seconds:
Overview Spring Data provides many ways to define a query that we can execute. One of these is the @Query annotation. In this tutorial, we'll demonstrate how to use the @Query annotation in Spring Data JPA to execute both JPQL and native SQL queries. We'll also show how to build a dynamic query when the @Query annotation is not enough.
@Transactional annotation do not work on jdbc read timeout exception. Thanks for contributing an answer to Stack Overflow! Please be sure to answer the question. Provide details and share your research!
Introduction When persisting Java objects into database records using an Object-Relational Mapping (ORM) framework, we often want to ignore certain fields. If the framework is compliant with the Java Persistence API (JPA), we can add the @Transient annotation to these fields.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With