django/innodb - 旧会话和交易的问题

Bac*_*con 4 mysql django innodb celery

我们刚刚将MySQL数据库从MyIsam切换到Innodb,我们看到Django出现了一个奇怪的问题.每当我们进行数据库事务时,现有的会话都不会捡起它...... 我们可以从mysql终端看到数据库中的新记录,但是现有的django会话(即已经打开的shell)不会注册更改.例如:

壳牌1:

>>> my_obj = MyObj.objects.create(foo="bar")
>>> my_obj.pk
1
Run Code Online (Sandbox Code Playgroud)

壳牌2(在上述之前开放)

>>> my_obj = MyObj.objects.filter(pk=1)
[]
Run Code Online (Sandbox Code Playgroud)

Shell 3(MySQL):

mysql> select id from myapp_my_obj where id = 1;
id
1
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么会发生这种情况?

编辑:为了澄清,Shell 2在Shell 1之前打开,然后我创建了Shell 1,然后我尝试查看我在Shell 2中创建的对象.

编辑2:总的来说,我有一个芹菜任务正在从创建的对象传递主键.当我使用MyISAM时,它每次都找到它,现在它会抛出ObjectDoesNotExist,即使我可以看到该对象是在数据库中创建的.

Pau*_*lan 7

您的create()命令提交当前shell的事务,但不对第二个shell中的事务执行任何操作.

https://docs.djangoproject.com/en/dev/topics/db/transactions/

你的第二个线程无法看到第一个线程在第一个线程中完成,因为它在自己的事务中.事务隔离数据库,以便在提交事务时,所有事件都在单个时间点发生,包括select语句.这是AACID.试试跑步

from django.db import transaction; transaction.commit()
Run Code Online (Sandbox Code Playgroud)

在第二个shell中.这应该提交当前事务并开始一个新事务.transaction.rollback()如果你没有修改当前shell中db的任何内容,你也可以使用同样的东西.

编辑编辑:

您可能需要获取特定的数据库连接才能使其正常工作.试试这个:

import django.db
django.db.connection._commit() 
Run Code Online (Sandbox Code Playgroud)

有关此问题的更多信息:

http://groups.google.com/group/django-users/msg/55fa3724d2754013

相关的一点是:

If you want script1.py (using an InnoDB table) to see committed updates from 
other transactions you can change the transaction isolation level like so: 

from django.db import connection 
connection.cursor().execute('set transaction isolation level read 
committed') 

Alternatively you can enable the database's version of auto-commit, which 
"commits" queries as well as updates, so that each new query by script1 will 
be in its own transaction: 

connection.cursor().execute('set autocommit=1') 
Either one allows script1 to see script2's updates. 

所以,tl; dr是你需要设置你的InnoDB事务隔离READ-COMMITTED.