gpt4 book ai didi

python - Django 数据库事务和死锁

转载 作者:行者123 更新时间:2023-11-29 05:35:21 25 4
gpt4 key购买 nike

当使用 Gunicorn 和多个进程/工作线程运行 Django 时,我遇到了一些手动 MySQL 数据库事务的死锁问题。

DatabaseError(1205, 'Lock wait timeout exceeded; try restarting transaction')

我的设置使用多个数据库,我的函数需要传递数据库以在调用时使用。因此,我不能使用标准 Django transaction decorators因为数据库需要硬编码为参数。我检查了装饰器代码以查看事务是如何管理的,我的函数如下所示:

from django.db import connections

def process(self, db, data):

# Takeover transaction management
connections[db].enter_transaction_management(True)
connections[db].managed(True)

# Process
try:
# do things with my_objects...
for obj in my_objects:
obj.save(using=db)
connections[db].commit()
except Exception as e:
connections[db].rollback()
finally:
connections[db].leave_transaction_management()

谁能发现这里可能出了什么问题?

最佳答案

请注意,您可能希望使用更清晰的 with 风格的语法。下面的代码应该与上面的代码相同,但更像 pytonic。

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
}
}

关于python - Django 数据库事务和死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11213481/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com