sql >> Databáze >  >> RDS >> Mysql

Hibernate:Při pokusu o získání zámku bylo zjištěno uváznutí

Protože k zablokování dochází tak často, vypadá to, že některá vlákna aplikace drží zámky po delší dobu.

Každé vlákno v aplikaci bude při přístupu k databázi používat své vlastní databázové připojení/připojení, takže z pohledu databáze jsou dvě vlákna dva odlišní klienti, kteří soutěží o uzamčení databáze.

Pokud vlákno drží zámky po delší dobu a získává je v určitém pořadí a přijde druhé vlákno, které získává stejné zámky, ale v jiném pořadí, nutně dojde k uváznutí (viz zde podrobnosti o této časté příčině zablokování).

Při operacích čtení také dochází k uváznutí, což znamená, že některá vlákna získávají také zámky čtení. K tomu dochází, pokud vlákna provádějí transakce v REPEATABLE_READ úroveň izolace nebo SERIALIZABLE .

Chcete-li to vyřešit, zkuste vyhledat použití Isolation.REPEATABLE_READ a Isolation.SERIALIZABLE v projektu, abyste zjistili, zda se používá.

Jako alternativu použijte výchozí READ_COMMITTED úroveň izolace a označte entity pomocí @Version , ke zpracování souběžnosti pomocí optimistického zamykání místo toho.

Zkuste také identifikovat dlouho běžící transakce, to se někdy stává, když je @Transactional je umístěn na nesprávném místě a zabalí například zpracování celého souboru do příkladu dávkového zpracování, místo aby transakce prováděl řádek po řádku.

Toto je konfigurace log4j pro protokolování vytváření/mazání správců entit a zahájení/potvrzení/vrácení transakcí:

   <!-- 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. Mohu nějak provést aktualizační dotaz (buď JPA/Native), aniž bych musel zamykat tabulku přes @Transactional?

Aktualizační dotazy jsou možné prostřednictvím nativních dotazů nebo JPQL .

  1. Mohu se nějak dostat do relace bez použití @Transactional? Například plánované vlákno se pokusí přečíst pole Lazy na Entity výnosy LazyInitializationException – žádná relace, pokud metoda není označena @Transactional

V metodách bez @Transactional , budou dotazy prováděny v jeho vlastním správci entit a vrátí pouze oddělené entity, protože tato relace je uzavřena ihned po spuštění dotazu.

takže výjimky z líné inicializace v metodách bez @Transactional je normální. Můžete je nastavit na @Transactional(readOnly=true) také.



  1. Vypočítejte počet záznamů pro každé datum mezi 2 daty

  2. MySQL získává řádky, ale dává přednost jedné hodnotě sloupce před jinou

  3. Jak zaokrouhlit časové razítko v MySQL

  4. Jak vám fóra zobrazují nepřečtená témata?