I am using Spring Boot, Spring Data, JPA(Hibernate) and MySQL in my project. Here is a method signature from my repository interface:
@Lock(LockModeType.PESSIMISTIC_READ)
@QueryHints({ @QueryHint(name = "javax.persistence.lock.timeout", value = "5000") })
@Query("select b from book b where b.id = :bookId")
Optional<Book> findBookCustom(Long bookId);
When I inspect the SQL logs, I can see that "for shared" clause is appended to the select statement.
This is a quote from MySQL documentation regarding shared locks:
If any of these rows were changed by another transaction that has not yet committed, your query waits until that transaction ends and then uses the latest values.
I can actually trigger the blocking behaviour by updating the book from another thread. When I suspend the updating thread (after book is updated) and then start the reading thread, I can see that the reading thread is blocked. The problem is that the reading thread waits for about 50 seconds (this is the default wait value, I suppose) until the timeout exception is thrown. The value 5000 I provide in QueryHint does not take effect. I also tried using the EntityManager directly to issue the JPQL select statement, but the result was same. Any ideas on how i can set the timeout to 5 seconds?