Deadlock with background EntityManager bootstrap due to locking in getSingletonFactoryBeanForTypeCheck #34247
Labels
in: core
Issues in core modules (aop, beans, core, context, expression)
type: regression
A bug that is also a regression
Milestone
Hi team,
A user reported an issue on my project (jdbc-observations/datasource-micrometer#54) with a sample repro where the application hangs during startup. Upon debugging, I traced this change (384dc2a) for
6.2.1
caused the issue.Conditions:
EntityManager
creationspring.data.jpa.repositories.bootstrap-mode
is set tolazy
ordeferred
(handled byJpaRepositoriesAutoConfiguration
).BeanFactory
access in beans associated withEntityManager
DataSource
) accessed lazily viaObjectProvider
duringEntityManagerFactory
creation.Problem:
A deadlock occurs between the main thread and the background thread creating the
EntityManagerFactory
.singletonLock
while waiting for theEntityManagerFactory
to be created.EntityManagerFactory
is being created in a separate thread, and a dependent bean in that process tries to lazily access theBeanFactory
viaObjectProvider
.ObjectProvider
access in the background thread tries to acquire thesingletonLock
, leading to a deadlock.Detailed Code Flow:
Background Thread:
LocalContainerEntityManagerFactoryBean
initiates the creation of theEntityManagerFactory
(NativeEntityManagerFactory
) in a separate thread (via a task submission, holding aFuture
for the result).Main Thread:
JpaMetamodelMappingContextFactoryBean
.JpaMetamodelMappingContextFactoryBean
(a subclass ofAbstractFactoryBean
) invokes itsafterPropertiesSet()
method to create a bean whilesingletonLock
is acquired.JpaMetamodelMappingContext
, a call togetMetamodels()
is made, which invokes a proxy and callsAbstractEntityManagerFactoryBean#getNativeEntityManagerFactory()
. This method calls a blocking call to theFuture
, waiting for the background thread to completeEntityManagerFactory
creation.Background Thread (Continued):
EntityManagerFactory
creation, JDBC-related beans (e.g.,DataSource
) are instantiated.datasource-micrometer
, theDataSource
bean references other beans, one of which lazily resolves anobservationRegistry
viaObjectProvider
.ObjectProvider
to attempt to access thebeanFactory
. It tries to acquire thesingletonLock
, which is already held by the main thread, resulting in a deadlock.This is a repro sample code capturing the above scenario concept:
Simple Repro Code
I'm not sure if this is to be called a regression or a new requirement for
6.2.1
.If it is a new behavior, the limitation would be that any
EntityManager
infrastructure beans (such as beans related toDataSource
) cannot have lazy access to theBeanFactory
when backgroundEntityManager
bootstrap is enabled due to the use of a separate thread.The text was updated successfully, but these errors were encountered: