3

I have some code that would be a lot simpler with nested calls to select_for_update(), but I'm afraid I'm setting myself up for a deadlock.

Example:

with transaction.atomic():
    uu1 = UniUser.objects.select_for_update().get(pk=uupk)
    with transaction.atomic():
        uu2 = UniUser.objects.select_for_update().get(pk=uupk)  # why no deadlock here??
        uu2.bio = 'i like pizza'
        uu2.save()
    uu1.bio = 'i like pie'
    uu1.save()

I would have expected the second select_for_update() to deadlock since it's trying to lock an already locked record, but this code runs just fine and we end up with 'i like pie' in the bio. Ditto if I remove the inner transaction and just lock the same record twice in the same transaction.

Why is there no deadlock here? Is this safe code?

In case the answer is database specific, I'm using Postgres.

mgalgs
  • 15,671
  • 11
  • 61
  • 74

1 Answers1

3

The lock is acquired and held by your transaction.

When you attempt to grab it again, nothing happens as your transaction already hods a lock on that row.

Mike Organek
  • 11,647
  • 3
  • 11
  • 26