Sample Header Ad - 728x90

What kind of deadlock the deadlock_timeout config parameter detects in Postgresql?

3 votes
1 answer
7160 views
My overall goal is to get a 40P01/ERRCODE_T_R_DEADLOCK_DETECTED from postgres when an deadlock is detected. (To be more precise, I would like to get a LockAcquisitionException in Hibernate, which is the exception the 40P01/ERRCODE_T_R_DEADLOCK_DETECTED error code is translated in PostgreSQL81Dialect.java ) I use Postgresql 9.6. For this I thought I should set the deadlock_timeout and log_lock_waits config variables as suggested by 19.12. Lock Management > deadlock_timeout (integer) This is the amount of time, in > milliseconds, to wait on a lock before checking to see if there is a > deadlock condition. > [...] > When log_lock_waits is set, this parameter also determines the length > of time to wait before a log message is issued about the lock wait. If > you are trying to investigate locking delays you might want to set a > shorter than normal deadlock_timeout. I've set the following values in postgresql.conf log_lock_waits = on # log lock waits >= deadlock_timeout deadlock_timeout = 5s Now, when I create a deadlock situtation (from Java using Hibernate) I find the following in the postgresql.log LOG: process 17493 still waiting for ShareLock on transaction 322815 after 5000.464 ms DETAIL: Process holding the lock: 17495. Wait queue: 17493. CONTEXT: while updating tuple (132,35) in relation "publication" However no 40P01/ERRCODE_T_R_DEADLOCK_DETECTED error is generated (and sent to the JDBC driver). I digged a little but into the postgres source code and found that the dead lock detection done by setting deadlock_timeout/log_lock_waits is a different mechanism than the one generating 40P01/ERRCODE_T_R_DEADLOCK_DETECTED. The deadlock_timeout case is handled in backend/storage/lmgr/proc.c , while the 40P01/ERRCODE_T_R_DEADLOCK_DETECTED case in backend/storage/lmgr/deadlock.c So, my questions are: - Are these actually two different types of deadlocks that are detected? - Is there a way to get an error when deadlock_timeout based deadlock detection happens? - How can actually a ERRCODE_T_R_DEADLOCK_DETECTED error be forced to happen? **UPDATE**: the code I use to get into the deadlock situation goes like this (Spring/Java): // This is in a Transaction managed by spring Publication p = em.find(Publication.class, id); p.setComment("Outer "+new Date()); em.flush(); // This utility method runs the lambda expression in a new Transaction // using Spring's TransactionTemplate and tries to update // the same Publication that is about to be updated by the // "outer" transaction Utils.runInSeparateTransaction(status -> { Publication p2 = em.find(p.getClass(), p.getMtid()); p2.setComment("Inner "+new Date()); return p2; // Would flush/commit after the return, but will "hang" instead. // Here I would expect the deadlock error but only get the // deadlock log. }; // Outer transaction would commit at this point but will
Asked by Balázs E. Pataki (95 rep)
Jan 16, 2018, 10:13 AM
Last activity: Jun 29, 2018, 02:03 PM