django会在第一次查询时创建隐式事务吗?

时间:2012-08-27 20:25:52

标签: sql django transactions innodb

我有django 1.3.1,python2.6和MySQL 5.5.20。 setting.py中的init_command设置为SET storage_engine=INNODB

我有以下情况:

考虑模型:

class Fruit(models.Model):
    name = models.CharField(max_length=50)

    def __unicode__(self):
        return self.name

现在我打开两个Django shell并输入:

django shell I:

./manage.py shell
(InteractiveConsole)
>>> import fruits.models as m
>>> m.Fruit(name="apple").save()
>>> m.Fruit.objects.get(pk=1)    
<Fruit: apple>

django shell II:

./manage.py shell
(InteractiveConsole)
>>> import fruits.models as m
>>> m.Fruit.objects.get(pk=1)    
<Fruit: apple>

到目前为止一切顺利。现在我继续输入 shell I

>>> m.Fruit(name="peach").save()
>>> m.Fruit.objects.get(pk=2)
<Fruit: peach>

问题:为什么在 shell II 中键入以下内容后找不到对象?

>>> m.Fruit.objects.get(pk=2)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "..../django/db/models/manager.py", line 132, in get
    return self.get_query_set().get(*args, **kwargs)
  File "..../django/db/models/query.py", line 349, in get
    % self.model._meta.object_name)
DoesNotExist: Fruit matching query does not exist.

我发现使shell II具有“新面貌”的唯一方法是:

>>> from django.db import transaction
>>> transaction.enter_transaction_management()
>>> transaction.rollback()

如果我想确定orm不会“撒谎”,我每次查询水果时都需要roolback()

1 个答案:

答案 0 :(得分:2)

这是一个日晒问题。您可以放松到“隔离级别读取提交”以避免此行为。另外,了解这种对日照水平的影响(phantoms)。

要为您的django项目将Read Commited Isolation Level设置为MySQL,您应该在settings.py中设置此参数:

DATABASE_OPTIONS = { 
     "init_command": 'SET storage_engine=INNODB,    \
                      SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED', }