0

I am going through a block of legacy code (Python2.6 and Django1.3.3) to acquire lock. Backend is Oracle.

Refer quoted block of code. What is the need for len(query set) on line number 8? I am particularly puzzled due to comment in line number 7. This particular line is consuming time in iterating through large number of records in query set. I am trying to know the reason to have this line before removing it.

I will test this code and update here. I will try without this line and also try replace len with .count() method.

lock_acquired = False
while not lock_acquired:
    try:
        where_clause= "is_deleted=0"
        avail_emp = Employee.objects.select_for_update(nowait=True).extra(where=[where_clause])
        log.debug("Acquiring lock")
        # *****Please dont remove below log to handle multiple requests at a time while rows are locked by a request*****
        log.debug(len(avail_emp))
        lock_acquired = True
        log.debug("Lock acquired")
    except Exception, e:
        log.debug("%s - Waiting for 2 secs before retry " %str(e))
        sleep(2)
Soundar
  • 171
  • 7

1 Answers1

0

avail_emp will contain a query object, but queries in django are 'lazy' iterators, which means they are not actually run until the values are requested. In order to actually have the select_for_update() execute as SQL, the query needs to be evaluated, but we don't care about the results of the query, only the locking behavior. Asking for the len() of the iterator is enough to trigger the evaluation of the query. Since we don't care about fetching the results, this (maybe) prevents fetching the objects into memory.

Alternatively, we could fetch the objects to get the same effect:

log.debug(list(avail_emp))
Seth
  • 2,712
  • 3
  • 25
  • 41