Django可以在线程模型中运行吗?

时间:2012-07-07 12:45:24

标签: django

我正在查看代码库,特别是数据库连接部分,并且遇到了这个问题。

首先,使用以下stamentent获取光标到数据库:

from django.db import connection, transaction
cursor = connection.cursor()

connection是一个模块属性,因此在线程模型中,所有线程都将共享该变量。听起来有点奇怪。进一步潜水,cursor()方法属于django.db.backends.BaseDatabaseWrapper,如下所示:

def cursor(self):
        self.validate_thread_sharing()
        if (self.use_debug_cursor or
            (self.use_debug_cursor is None and settings.DEBUG)):
            cursor = self.make_debug_cursor(self._cursor())
        else:
            cursor = util.CursorWrapper(self._cursor(), self)
    return cursor

密钥是对_cursor()的调用,它执行正在使用的数据库的后端代码。对于MySQL,它在django.db.backends.mysql.DatabaseWrapper上执行_cursor()方法,如下所示:

def _cursor(self):
    new_connection = False
    if not self._valid_connection():
        new_connection = True
        kwargs = {
            'conv': django_conversions,
            'charset': 'utf8',
            'use_unicode': True,
        }
        settings_dict = self.settings_dict
        if settings_dict['USER']:
            kwargs['user'] = settings_dict['USER']
        if settings_dict['NAME']:
            kwargs['db'] = settings_dict['NAME']
        if settings_dict['PASSWORD']:
            kwargs['passwd'] = settings_dict['PASSWORD']
        if settings_dict['HOST'].startswith('/'):
            kwargs['unix_socket'] = settings_dict['HOST']
        elif settings_dict['HOST']:
            kwargs['host'] = settings_dict['HOST']
        if settings_dict['PORT']:
            kwargs['port'] = int(settings_dict['PORT'])
        # We need the number of potentially affected rows after an
        # "UPDATE", not the number of changed rows.
        kwargs['client_flag'] = CLIENT.FOUND_ROWS
        kwargs.update(settings_dict['OPTIONS'])
        self.connection = Database.connect(**kwargs)
        self.connection.encoders[SafeUnicode] = self.connection.encoders[unicode]
        self.connection.encoders[SafeString] = self.connection.encoders[str]
        connection_created.send(sender=self.__class__, connection=self)
    cursor = self.connection.cursor()
    if new_connection:
        # SQL_AUTO_IS_NULL in MySQL controls whether an AUTO_INCREMENT column
        # on a recently-inserted row will return when the field is tested for
        # NULL.  Disabling this value brings this aspect of MySQL in line with
        # SQL standards.
        cursor.execute('SET SQL_AUTO_IS_NULL = 0')
    return CursorWrapper(cursor)

因此不一定要创建新游标。如果已经调用了_cursor(),则返回先前使用的游标。

在线程模型中,这意味着多个线程可能共享相同的数据库游标,这似乎是禁止的。

还有其他迹象表明Django中不允许使用线程。来自django / db / init .py的模块级代码,例如:

def close_connection(**kwargs):
    for conn in connections.all():
        conn.close()
signals.request_finished.connect(close_connection)

因此,如果任何请求完成,则关闭所有数据库连接。如果有并发请求怎么办?

似乎正在共享许多内容,这表明不允许进行线程化。我没有在任何地方看到同步代码。

谢谢!

0 个答案:

没有答案