I've found some references indicating that it does this, but the lock on the parent table had to be shared to prevent the deletion of the row from the parent table.
What makes me suspect it's a lock on the parent table is the word "ShareLock" in the logs. A SELECT ... FOR UPDATE statement shouldn't place that type of lock on the table it's selecting. On Sunday, March 8, 2026 at 12:19:35 PM GMT-4, Shaheed Haque <[email protected]> wrote: On Sun, 8 Mar 2026 at 15:15, <[email protected]> wrote: This is pure speculation. It's possible that using SELECT FOR UPDATE also locks the rows in the parent tables referenced in the field list. I believe this happened in older versions of PostgreSQL. Interesting. In the query, paiyroll_endpoint.op_id and paiyroll_endpoint.client_id ARE foreign keys to other tables. But I don't see any reference to locking rows in parent tables in the docs around https://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-ROWS. A quick poke around did not reveal any documentation that confirms this one way or another. And to my admittedly in-expert thinking, it seems surprising that the parent might need to be locked? On Saturday, March 7, 2026 at 04:25:01 AM GMT-5, Shaheed Haque <[email protected]> wrote: [I originally posted this over at https://forum.djangoproject.com/t/unexpected-deadlock-across-two-separate-rows-using-postgres-17-and-select-for-update/44294/1, but that thread ran into a dead end. Apologies for the cross-post] Hi, I'm trying to understand/fix a rare deadlock in my application. Given my limited knowledge, what seems odd to me is that the deadlock involves two processes running exactly the same code/query, each of which (tries to) avoid issues by locking exactly one row for update. In Django-speak, the code does this:
