Hibernate: Deadlock found when trying to obtain lock

后端 未结 2 1051
感动是毒
感动是毒 2021-02-04 09:29

I am using hibernate in my project and I am getting random Apparent Deadlocks for very simple database operations.

There is one of the Stack Traces: https://gist.github.

2条回答
  •  南笙
    南笙 (楼主)
    2021-02-04 09:43

    This is the error with MySQL.

    The most easy way to resolve & avoid deadlocks is to reorder the DB operations happening in the application.

    Deadlock mostly occurs when more than one resource/connection try to acquire more than one lock at opposite orders, as below:

    connection 1: locks key(1), locks key(2);
    connection 2: locks key(2), locks key(1);
    

    In the scenario when both the connections execute at the same time, connection 1 will acquire lock on key(1), and connection 2 on key(2). After that both the connections will wait for other to release the lock on the key. This results in deadlock.

    But, a little tweak in the order of the transactions, then deadlocks can be avoided.

    connection 1: locks key(1), locks key(2);
    connection 2: locks key(1), locks key(2);
    

    Above re-order is deadlock proof.

    Other ways to avoid deadlocks is to have a transaction management mechanism. Transaction management by Spring is almost plug-n-play. Moreover, you can have a deadlock retry policy in place. An interesting deadlock retry via Spring AOP can be found here. This way you just need to add the annotation to the method you want to retry in case of deadlock.

    For more debug logs on deadlock to find out which statements are suspicious, try running the "show engine innodb status" diagnostics. Also, you can have a look at How to Cope with Deadlocks.

    UPDATE: A scenario for deadlocks in transactional DB operations.

    In a transactional database, a deadlock happens when two processes each within its own transaction updates two rows of information but in the opposite order. For example, process A updates row 1 then row 2 in the exact time-frame process B updates row 2 then row 1. Process A can't finish updating row 2 until process B is finished, but it cannot finish updating row 1 until process A finishes. No matter how much time is allowed to pass, this situation will never resolve itself and because of this database management systems will typically kill the transaction of the process that has done the least amount of work.

    Shishir

提交回复
热议问题