sql >> Database >  >> RDS >> Mysql

Slaapstand:Deadlock gevonden bij het verkrijgen van vergrendeling

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 >
  1. 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 .

  1. 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.



  1. SQL Server - parameter snuiven

  2. PostgreSQL - GROUP BY-clausule of worden gebruikt in een aggregatiefunctie

  3. Hoe Round() werkt in SQLite

  4. PHP float/double opgeslagen als MySQL DECIMAL