My Postgres tables:
performers
- id
- rank
- group_id REFERENCES groups
performances
- id
- pay
- performer_id REFERENCES performers
groups
- id
I often need to select all the performers from a group and update all their ranks. But this often leads to deadlocks since I'm doing an SELECT ... FOR UPDATE select and other threads are INSERTing at the same time.
Example of the error I see a lot (in Python SqlAlchemy):
DBAPIError: (TransactionRollbackError) deadlock detected
DETAIL: Process 83182 waits for ShareLock on transaction 14282922; blocked by process 83171.
Process 83171 waits for ShareLock on transaction 14282925; blocked by process 83182.
HINT: See server log for query details.
'SELECT performers.id AS performers_id, performers.rank AS performers_rank, performers.group_id AS performers_group_id \nFROM performers \nWHERE performers.group_id = %(group_id_1)s FOR UPDATE' {'group_id_1': 2}
I've found a few examples of this behavior around as well.
How can I fix this? Can I switch to a different transaction locking level? I'd rather not just abort and have to retry - I want the database to take care of this contention for me.
There must be some way to fix this - what I want to do is quite simple.
performances, commit after each differentperformer_idto avoid cross-locking with the UPDATEs. The fact that it's aShareLockstrongly suggests that it's taken for the FK.