-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Closed
Description
Version: Spring Data JPA 3.3.0.
The method uses a synchronized block, causing thread pinning:
Lines 300 to 302 in 2316742
| synchronized (this.cachedCriteriaQuery) { | |
| return getEntityManager().createQuery(criteriaQuery); | |
| } |
In my application, I'm intercepting calls to EntityManager#createQuery and perform blocking operations in that interceptor. Due to the synchronized block, my virtual thread cannot dismount from the platform thread, therefore pinning it. Running with -Djdk.tracePinnedThreads=full produces stack traces that point to the snippet above:
Thread[#55,ForkJoinPool-1-worker-2,5,CarrierThreads]
java.base/java.lang.VirtualThread$VThreadContinuation.onPinned(Unknown Source)
java.base/jdk.internal.vm.Continuation.onPinned0(Unknown Source)
java.base/java.lang.VirtualThread.park(Unknown Source)
java.base/java.lang.System$2.parkVirtualThread(Unknown Source)
java.base/jdk.internal.misc.VirtualThreads.park(Unknown Source)
java.base/java.util.concurrent.locks.LockSupport.park(Unknown Source)
java.base/java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(Unknown Source)
java.base/java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(Unknown Source)
java.base/java.util.concurrent.CountDownLatch.await(Unknown Source)
reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:90)
reactor.core.publisher.Mono.block(Mono.java:1728)
my.company.MyInterceptor.blockingCall() //--------------- <---- My code here
java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source)
java.base/java.lang.reflect.Method.invoke(Unknown Source)
org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:637)
org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:620)
org.springframework.aop.aspectj.AspectJMethodBeforeAdvice.before(AspectJMethodBeforeAdvice.java:44)
org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:57)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:220)
jdk.proxy2/jdk.proxy2.$Proxy266.createQuery(Unknown Source)
org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.createQuery(PartTreeJpaQuery.java:297) <== monitors:1
org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.createQuery(PartTreeJpaQuery.java:242)
org.springframework.data.jpa.repository.query.PartTreeJpaQuery.doCreateQuery(PartTreeJpaQuery.java:113)
org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:239)
org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:223)
org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:92)
org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:149)
org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:137)
org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:170)
org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:158)
org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:164)
org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143)
Please consider replacing this (and other synchronized blocks/methods) with ReentrantLock to avoid thread pinning.
Metadata
Metadata
Assignees
Labels
type: bugA general bugA general bug