Eftersom deadlocks inträffar så ofta, ser det ut som att några av trådarna i applikationen håller lås under en längre tid.
Varje tråd i applikationen kommer att använda sin egen databasanslutning/anslutningar när de kommer åt databasen, så ur databasens synvinkel är två trådar två distinkta klienter som konkurrerar om databaslås.
Om en tråd håller lås under en längre tid och förvärvar dem i en viss ordning, och en andra tråd kommer och skaffar samma lås men i en annan ordning, är dödläge bestämt att uppstå (se här för detaljer om denna vanliga dödlägesorsak).
Även dödlägen uppstår i läsoperationer, vilket innebär att vissa trådar också får läslås. Detta händer om trådarna kör transaktioner i REPEATABLE_READ
isoleringsnivå eller SERIALIZABLE
.
För att lösa detta, försök att söka efter användningsområden för Isolation.REPEATABLE_READ
och Isolation.SERIALIZABLE
i projektet, för att se om detta används.
Som ett alternativ, använd standard READ_COMMITTED
isoleringsnivå och annotera enheterna med @Version
, för att hantera samtidighet med optimistisk låsning
istället.
Försök också att identifiera långa transaktioner, detta händer ibland när @Transactional
är placerad på fel ställe och lindar till exempel bearbetningen av en hel fil i exemplet med en batchbearbetning, istället för att utföra transaktioner rad för rad.
Detta är en log4j-konfiguration för att logga skapande/borttagning av enhetshanterare och transaktioner start/commit/rollback:
<!-- spring entity manager and transactions -->
<logger name="org.springframework.orm.jpa" additivity ="false">
<level value="debug" />
<appender-ref ref="ConsoleAppender" />
</logger >
<logger name="org.springframework.transaction" additivity ="false">
<level value="debug" />
<appender-ref ref="ConsoleAppender" />
</logger >
- Kan jag på något sätt utföra uppdateringsfrågan (antingen JPA/Native) utan att behöva låsa tabellen via @Transactional?
Uppdateringsfrågor är möjliga via inbyggda frågor eller JPQL .
- Kan jag på något sätt komma in i sessionen utan att använda @Transactional? Till exempel, schemalagd tråd försöker läsa Lazy-fältet på Entity yields to LazyInitializationException - ingen session, om metoden inte är kommenterad med @Transactional
I metoder utan @Transactional
, kommer frågor att köras i sin egen enhetshanterare och returnerar endast fristående enheter, eftersom sessionen stängs omedelbart efter att frågan har körts.
så de lata initieringsundantagen i metoder utan @Transactional
är normal. Du kan ställa in dem på @Transactional(readOnly=true)
likaså.