より明確なwith
を使用することをお勧めします。 -スタイルの構文。以下は上記のコードと同じである必要がありますが、よりピトニックです。
from django.db import transaction
from __future__ import with_statement
def process(self, db, data):
with transaction.commit_on_success(using=db):
# do things with my_objects...
for obj in my_objects:
obj.save(using=db)
またはデコレータ付き
from django.db import transaction
@transaction.commit_on_success(using=db)
def process(self, db, data):
# do things with my_objects...
for obj in my_objects:
obj.save(using=db)
ただし、デッドロックの問題は解決しません。
トランザクション分離レベルを下げると成功する可能性があります。これは、mysqlのデフォルトでREPEATABLE READ
ほとんどの使用法には厳しすぎます。 (OracleのデフォルトはREAD COMMITTED
')
これをsettings.py
に追加することで実現できます
MYSQL_DATABASE_OPTIONS = {'init_command': 'SET storage_engine=INNODB; SET
SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;'}
DATABASES = {
'default': { # repeat for each db
'ENGINE': ... etc
...
...
'OPTIONS': MYSQL_DATABASE_OPTIONS
}
}