【问题标题】:Can I avoid locking rows for unnecessary amounts of time [in Django]?我可以避免在不必要的时间内锁定行[在 Django 中]?
【发布时间】:2012-08-24 13:57:39
【问题描述】:

以下面的代码为例(忽略其功能上缺乏用处,因为它只是一个包含我需要的东西的简单示例):

@transaction.commit_on_success
def test_for_success(username)
    person = Person.objects.select_for_update().get(username=username)
    response = urllib2.urlopen(URL_TO_SOME_SLOW_API, some_data)
    if '<YES>' in response.read():
        person.successes += 1
        person.save()

我关于示例的问题与 when 查询命中数据库有关。显然,第一个查询将锁定Person 行,然后我调用了一个缓慢的 API,这可能需要 3 秒才能响应,从而导致该行被锁定 3 秒。我是否正确理解这一点,并且在我的事务中发生缓慢的 API 命中的情况下,如果我移动查询的位置以便 SELECT FOR UPDATE 直到 所有慢速 API 之后才会发生请求,这是否会产生一次不锁定我的行几秒钟的看似明显的效果(我的应用程序中 select_for_update 的情况是不可避免的)?或者,我是不是误会了,不知何故,直到事务结束才真正访问数据库?

【问题讨论】:

    标签: sql django select transactions transaction-isolation


    【解决方案1】:

    您对代码的假设是正确的。如果您查看select_for_update() 文档,此操作会锁定数据库中的这些行,直到它们被解锁。这实际上会在您的 urllib 请求期间锁定。

    如果您在请求之后将数据库调用移动到条件语句中,那么您再次正确的是,数据库将被锁定更短的时间(尽管如果多次调用,仍然会有一些客户端阻塞由于争用而调用)。

    【讨论】:

    • 啊,最糟糕的是我无法锁定行,更新它以反映 API 后的状态(与库存相关,所以我必须阻止并发捕获相同数量),然后调用API,然后回滚,如果 API 没有告诉我我想知道的内容。好吧,我可以,只是它仍然会阻塞,直到函数返回。呃,数据库:(
    猜你喜欢
    • 2021-12-12
    • 1970-01-01
    • 2019-04-07
    • 1970-01-01
    • 2014-04-27
    • 1970-01-01
    • 2015-03-27
    • 1970-01-01
    • 2011-10-08
    相关资源
    最近更新 更多