3

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

@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()

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

4

1 回答 1

1

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

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

于 2012-08-24T16:36:38.893 回答