Omdat de impasses zo vaak voorkomen, lijkt het erop dat sommige threads van de toepassing gedurende een langere periode vergrendelingen vasthouden.
Elke thread in de toepassing gebruikt zijn eigen databaseverbinding/-verbindingen bij het benaderen van de database, dus vanuit het oogpunt van de database zijn twee threads twee verschillende clients die strijden om databasevergrendelingen.
Als een thread locks voor een langere periode vasthoudt en ze in een bepaalde volgorde verwerft, en een tweede thread komt langs met dezelfde locks maar in een andere volgorde, dan zal er onvermijdelijk een deadlock optreden (zie hier voor details over deze vaak voorkomende impasse).
Er treden ook deadlocks op bij leesbewerkingen, wat betekent dat sommige threads ook leesvergrendelingen krijgen. Dit gebeurt als de threads transacties uitvoeren in REPEATABLE_READ
isolatieniveau of SERIALIZABLE
.
Om dit op te lossen, zoekt u naar gebruik van Isolation.REPEATABLE_READ
en Isolation.SERIALIZABLE
in het project, om te zien of dit wordt gebruikt.
Gebruik als alternatief de standaard READ_COMMITTED
isolatieniveau en annoteer de entiteiten met @Version
, om gelijktijdigheid af te handelen met behulp van optimistische vergrendeling
in plaats daarvan.
Probeer ook langlopende transacties te identificeren, dit gebeurt soms wanneer de @Transactional
wordt op de verkeerde plaats geplaatst en wikkelt bijvoorbeeld de verwerking van een heel bestand in het voorbeeld van een batchverwerking, in plaats van transacties regel voor regel uit te voeren.
Dit is een log4j-configuratie om het aanmaken/verwijderen van entiteitsmanagers en transacties begin/commit/rollback te loggen:
<!-- 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 ik op de een of andere manier een update-query uitvoeren (JPA/Native) zonder de tabel te vergrendelen via @Transactional?
Updatequery's zijn mogelijk via native queries of JPQL .
- Kan ik op de een of andere manier in een sessie komen zonder @Transactional te gebruiken? Geplande thread probeert bijvoorbeeld het Lazy-veld op Entity-opbrengsten te lezen voor LazyInitializationException - geen sessie, als de methode niet is geannoteerd met @Transactional
In methoden zonder @Transactional
, query's worden uitgevoerd in zijn eigen entiteitsmanager en retourneren alleen vrijstaande entiteiten, aangezien de sessie onmiddellijk wordt gesloten nadat de query is uitgevoerd.
dus de luie initialisatie-uitzonderingen in methoden zonder @Transactional
is normaal. Je kunt ze instellen op @Transactional(readOnly=true)
ook.