Fordi deadlocks sker så ofte, ser det ud til, at nogle af applikationens tråde holder låse i en længere periode.
Hver tråd i applikationen vil bruge sin egen databaseforbindelse/forbindelser, mens de får adgang til databasen, så fra databasens synspunkt er to tråde to forskellige klienter, der konkurrerer om databaselåse.
Hvis en tråd holder låse i en længere periode og erhverver dem i en bestemt rækkefølge, og der kommer en anden tråd, der får de samme låse, men i en anden rækkefølge, er dødlås bundet til at opstå (se her for detaljer om denne hyppige dødvandsårsag).
Også deadlocks forekommer i læseoperationer, hvilket betyder, at nogle tråde også opnår læselåse. Dette sker, hvis trådene kører transaktioner i REPEATABLE_READ
isolationsniveau eller SERIALIZABLE
.
For at løse dette, prøv at søge efter anvendelser af Isolation.REPEATABLE_READ
og Isolation.SERIALIZABLE
i projektet, for at se om dette bliver brugt.
Som et alternativ kan du bruge standard READ_COMMITTED
isolationsniveau og annotér enhederne med @Version
, for at håndtere samtidighed ved hjælp af optimistisk låsning
i stedet.
Prøv også at identificere langvarige transaktioner, dette sker nogle gange, når @Transactional
er placeret det forkerte sted og omslutter f.eks. behandlingen af en hel fil i eksemplet med en batchbehandling, i stedet for at udføre transaktioner linje for linje.
Dette er en log4j-konfiguration til at logge oprettelse/sletning af enhedsadministratorer og 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 jeg på en eller anden måde udføre opdateringsforespørgsel (enten JPA/Native) uden at skulle låse tabellen via @Transactional?
Opdateringsforespørgsler er mulige via indbyggede forespørgsler eller JPQL .
- Kan jeg på en eller anden måde komme i session uden at bruge @Transactional? For eksempel forsøger den planlagte tråd at læse Lazy-feltet på Entity yields to LazyInitializationException - ingen session, hvis metoden ikke er kommenteret med @Transactional
I metoder uden @Transactional
, vil forespørgsler blive udført i dens egen enhedsadministrator og returnerer kun adskilte enheder, da din session lukkes umiddelbart efter forespørgslen er kørt.
så de dovne initialiserings-undtagelser i metoder uden @Transactional
er normalt. Du kan indstille dem til @Transactional(readOnly=true)
også.