Django 事务和并发

Posted

技术标签:

【中文标题】Django 事务和并发【英文标题】:Django transactions and concurrency 【发布时间】:2012-10-22 04:15:53 【问题描述】:

我有一个视图需要对涉及需要锁定的共享资源的数据库执行更新(实现很复杂,但本质上只是一个共享计数器)。

为了保护自己免受竞争条件的影响,我使用的代码大致如下:

@transaction.commit_manually
def do_it(request):
    affected_models = Something.objects.select_for_update(blah = 1)

    for model in affected_models:
        model.modify()
        model.save()

    transaction.commit()

commit_manuallyselect_for_update()save() 的用法可以吗?我怎样才能写一个测试来证实这一点?例如,我找不到 Django 在事务之间触发的信号;我不能只是运行它并希望出现并发问题并得到处理。

【问题讨论】:

关于测试 Michael Foord 写了一个类似的问题,它提供了一个[测试模式][1]。它使用子进程。 [1]:voidspace.org.uk/python/weblog/arch_d7_2011_05_07.shtml caktusgroup.com/blog/2009/05/26/… 【参考方案1】:

为什么不在那里使用commit_on_success

我认为查询本身应该是这样的:

Something.objects.select_for_update().filter(...)

我不认为 django 在 select_for_update 上做任何你可以断言的特别之处。我脑海中唯一的断言是assertTrue(queryset.query.select_for_update)。它什么都不测试,只有在有人意外(?)删除呼叫时才有用。

即使您为此运行条件问题提出一些单元测试,我认为将其放入项目中也不明智。

更专注于测试您的代码,而不是数据库行为。

【讨论】:

以上是关于Django 事务和并发的主要内容,如果未能解决你的问题,请参考以下文章

在 Django Admin 中保存新对象并发送到 Celery 任务后,匹配查询不存在

数据库的事务处理和并发控制

分布式事务和事务并发控制

并发事务的问题和隔离级别

MySQL事务并发问题和MVCC机制

Sql Server并发和事务