Python 保持mysql连接的正确方法

Python 保持mysql连接的正确方法,python,mysql,Python,Mysql,我有一个24/7运行的应用程序,它使用mysql。它的不同功能使用mysql。实现它的一种方法是在应用程序中创建一个全局mysql实例,如下所示: self.db = MySQLdb.connect( host=self.settings.MYSQL_HOST_LOCAL, user=self.settings.MYSQL_USER, passwd=self.settings.MYSQL_PASS,

我有一个24/7运行的应用程序,它使用mysql。它的不同功能使用mysql。实现它的一种方法是在应用程序中创建一个全局mysql实例,如下所示:

self.db = MySQLdb.connect(
            host=self.settings.MYSQL_HOST_LOCAL,
            user=self.settings.MYSQL_USER,
            passwd=self.settings.MYSQL_PASS,
            db=self.settings.MYSQL_DB,
            use_unicode=True,
            charset="utf8",
        )
并使用
self.db.execute(…)
执行命令。通过这样做,应用程序使用1个连接。另一种方法是在每次需要执行事务时创建连接

方法1,防止应用程序一次又一次地创建和删除连接,但如果保持理想状态,它将面临“mysql消失”问题。方法2“mysql消失”没有问题,但它有太多的I/O


我很确定这两种方法都不正确,但正确的方法是什么?

一种方法是在每次需要执行时创建一个连接。您还可以创建一个函数来为您执行此操作。这就是它的本意。这不是太多的I/O

您还可以执行以下操作:

while True:
    try:
        db_session.execute('SELECT * FROM table')
        break
    except SQLAlchemyError:
        db_session.rollback()

如果连接已断开,这将引发异常,会话将回滚,重试可能会成功。(第一种解决方案要好得多)

在方法1中,根据应用程序场景,“MySQL服务器已经消失”可能是因为

You have encountered a timeout on the server side and the automatic reconnection in the client is disabled (the reconnect flag in the MYSQL structure is equal to 0).
当出现异常“MySQL服务器已消失”时,您可以向任何类似这样的db处理程序函数添加装饰程序,以重新连接MySQL db

class DB:
    """Database interface"""

    def retry(func):
        def call(self, *args, **kwargs):
            lock.acquire()
            try:
                return func(self, *args, **kwargs)
            except MySQLdb.Error, e:
                if 'MySQL server has gone away' in str(e):
                    # reconnect MySQL
                    self.connect_mysql()
                else:
                    # No need to retry for other reasons
                    pass
            finally:
                lock.release()
        return call

    def __init__(self):
        pass

    def connect_mysql(self):
        # do connection

    @retry
    def db_handler_function(self):
        # do something

“但是它有太多的I/O。”-你是怎么确定的?我指的是每次选择或更新都有太多的I/O,我创建了一个新的连接。这算不上“太多”?方法2几乎总是正确的方法。让连接池来做吧,这是一件很奇怪的事情……顺便说一句,在你知道自己有问题之前,你似乎在试图解决问题。@MitchWheat thanx,你能给我提供一个参考吗?那么我应该在每次交易结束时关闭数据库连接吗?我正在使用MySQLdb。假设我在函数的开头创建了一个新实例。如果我不关闭它,实例将被删除,那么连接会发生什么情况?现在可以了,还是应该在函数返回之前关闭它?Thanx,我考虑过了,但我的主要问题是哪种方法是正确的。我对这两种方法都有解决方案,但都不够好,