【问题标题】:Django: what is the need for len(queryset) after select_for_update(nowait=True)Django:在 select_for_update(nowait=True) 之后需要什么 len(queryset)
【发布时间】:2018-07-16 13:48:29
【问题描述】:

我正在通过一段遗留代码(Python2.6 和 Django1.3.3)来获取锁。后端是 Oracle。

参考引用的代码块。第 8 行需要 len(query set) 是什么?由于第 7 行中的注释,我特别困惑。这一行在遍历查询集中的大量记录时非常耗时。我想知道在删除它之前有这条线的原因。

我将测试此代码并在此处更新。我将尝试不使用此行,并尝试将 len 替换为 .count() 方法。

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)

【问题讨论】:

    标签: transactions database-concurrency


    【解决方案1】:

    avail_emp 将包含一个查询对象,但 django 中的查询是“惰性”迭代器,这意味着它们在请求值之前不会实际运行。为了真正让select_for_update() 作为 SQL 执行,查询需要被评估,但我们不关心查询的结果,只关心锁定行为。请求迭代器的 len() 足以触发查询的评估。由于我们不关心获取结果,这(也许)会阻止将对象获取到内存中。

    或者,我们可以获取对象以获得相同的效果:

    log.debug(list(avail_emp))
    

    【讨论】:

      猜你喜欢
      • 2018-08-03
      • 1970-01-01
      • 2012-09-06
      • 2012-12-28
      • 2015-11-25
      • 2021-09-21
      • 1970-01-01
      • 2016-09-10
      • 1970-01-01
      相关资源
      最近更新 更多