Explicación detallada de los parámetros de lectura del código fuente pooledDB del grupo de conexiones de Python

Explicación detallada de los parámetros de pooledDB

de DBUtils.PooledDB importar PooledDB

self.__pool = PooledDB(creator=pymysql,
                       mincached=1, 
                       maxcached=4, # 连接池中最大空闲连接数
                       maxconnections=4,#允许的最大连接数
                       blocking=True,# 设置为true,则阻塞并等待直到连接数量减少,false默认情况下将报告错误。
                       ping=1,#默认=1表示每当从池中获取时,使用ping()检查连接
                       host=self.host,
                       port=self.port,
                       user=self.user,
                       passwd=self.passwd,
                       db=self.db_name,
                       charset=self.charset
                      )
  • mincached: la conexión inactiva inicial en el grupo de conexiones, el valor predeterminado 0 o Ninguno significa que no hay conexión cuando se crea el grupo de conexiones. Sin embargo, al comparar el código fuente y los resultados experimentales, este parámetro no funciona.

    # PooledDB.py源码 267行
    idle = [self.dedicated_connection() for i in range(mincached)]
    while idle:
        idle.pop().close()
    # 确实是创建连接池时创建了mincached个连接,但返回之前都关闭了。所以创建好的时候并没有mincached个初始连接
    
  • maxcached: el número máximo de conexiones inactivas en el grupo de conexiones, el valor predeterminado 0 o Ninguno significa que no hay límite de tamaño del grupo de conexiones

  • maxshared: el número máximo de conexiones compartidas. Predeterminado 0 o Ninguno significa que todas las conexiones están dedicadas

  • maxconnections: el número máximo de conexiones permitidas, por defecto 0 o Ninguno significa que no hay límite de conexión

    # PooledDB.py源码 255行
    if maxconnections:
    	if maxconnections < maxcached:
    		maxconnections = maxcached
    	if maxconnections < maxshared:
    		maxconnections = maxshared
    	self._maxconnections = maxconnections
    else:
    	self._maxconnections = 0
    # maxcached、maxshared同时影响maxconnections
    # maxconnections=max(maxcached, maxshared)
    
    # PooledDB.py源码 356行
    	# 当收到一个连接放回请求时
        # if 没有最大空闲连接数限制,或现在的空闲连接数小于最大空闲连接数,则将事务回滚,并将这个连接放回空闲连接处;
        # else:直接关闭
        def cache(self, con):
            """Put a dedicated专用 connection back into the idle空闲 cache."""
            self._lock.acquire()
            try:
                if not self._maxcached or len(self._idle_cache) < self._maxcached:
                    con._reset(force=self._reset)  # rollback possible transaction
                    # the idle cache is not full, so put it there
                    self._idle_cache.append(con)  # append it to the idle cache
                else:  # if the idle cache is already full,
                    con.close()  # then close the connection
                self._connections -= 1
                self._lock.notify()
            finally:
                self._lock.release()
    # cache方法被使用
        def close(self):
            """Close the pooled dedicated connection."""
            # Instead of actually closing the connection,
            # return it to the pool for future reuse.
            if self._con:
                self._pool.cache(self._con)
                self._con = None
    
  • bloqueo: Verdadero significa bloquear y esperar cuando no hay conexión libre disponible; Falso significa informar un error directamente. El valor predeterminado es falso.

  • máximo: los tiempos máximos de reutilización de una sola conexión, el valor predeterminado 0 o Ninguno significa reutilización infinita, cuando se alcanza el número máximo de uso de la conexión, la conexión se restablecerá.

    # SteadyDB.py 483行
    if self._maxusage:
    	if self._usage >= self._maxusage:
            # the connection was used too often
            raise self._failure
    cursor = self._con.cursor(*args, **kwargs)  # try to get a cursor
    
  • setsession: lista opcional de comandos SQL que pueden servir para preparar la sesión, sentencias SQL que se ejecutarán al conectarse.

    # SteadyDB.py 298行
        def _setsession(self, con=None):
            """Execute the SQL commands for session preparation."""
            if con is None:
                con = self._con
            if self._setsession_sql:
                cursor = con.cursor()
                for sql in self._setsession_sql:
                    cursor.execute(sql)
                cursor.close()
    
  • restablecer: Cómo se restablece la conexión cuando se vuelve a colocar en el grupo de conexiones, el valor predeterminado es Verdadero. self._transaction solo se establece en True dentro de begin(). Cuando el valor predeterminado es Verdadero, si es verdadero, la transacción se revertirá cada vez que se devuelva el grupo de conexiones, y si es falso, solo se revertirá la transacción abierta explícitamente por begin().

        def cache(self, con):
            """Put a dedicated connection back into the idle cache."""
            self._lock.acquire()
            try:
                if not self._maxcached or len(self._idle_cache) < self._maxcached:
                    con._reset(force=self._reset)  # rollback possible transaction
                    # the idle cache is not full, so put it there
                    self._idle_cache.append(con)  # append it to the idle cache
                else:  # if the idle cache is already full,
                    con.close()  # then close the connection
                self._connections -= 1
                self._lock.notify()
            finally:
                self._lock.release()
     
        def _reset(self, force=False):
            """Reset a tough connection.
    
            Rollback if forced or the connection was in a transaction.
    
            """
            if not self._closed and (force or self._transaction):
                try:
                    self.rollback()
                except Exception:
                    pass
                
        def begin(self, *args, **kwargs):
            """Indicate the beginning of a transaction.
    
            During a transaction, connections won't be transparently
            replaced, and all errors will be raised to the application.
    
            If the underlying driver supports this method, it will be called
            with the given parameters (e.g. for distributed transactions).
    
            """
            self._transaction = True
            try:
                begin = self._con.begin
            except AttributeError:
                pass
            else:
                begin(*args, **kwargs)
    
  • fallas: Clase de excepción suplementaria, si (OperationalError, InternalError) estos dos no son suficientes.

    except self._failures as error:
    
  • ping: La explicación oficial es (0 = Ninguno = nunca, 1 = predeterminado = cuando se llama a _ping_check(), 2 = siempre que se crea un cursor, 4 = cuando se ejecuta una consulta, 7 = siempre y todas las demás combinaciones de bits de estos valores es una colección de las situaciones anteriores), pero en el código fuente solo se distingue si es distinto de cero, parece que la cantidad de valores no tiene mucho sentido.

        def _ping_check(self, ping=1, reconnect=True):
            """Check whether the connection is still alive using ping().
    
            If the the underlying connection is not active and the ping
            parameter is set accordingly, the connection will be recreated
            unless the connection is currently inside a transaction.
    
            """
            if ping & self._ping:
                try:  # if possible, ping the connection
                    alive = self._con.ping()
                except (AttributeError, IndexError, TypeError, ValueError):
                    self._ping = 0  # ping() is not available
                    alive = None
                    reconnect = False
                except Exception:
                    alive = False
                else:
                    if alive is None:
                        alive = True
                    if alive:
                        reconnect = False
                if reconnect and not self._transaction:
                    try:  # try to reopen the connection
                        con = self._create()
                    except Exception:
                        pass
                    else:
                        self._close()
                        self._store(con)
                        alive = True
                return alive
    

Instrucciones

    def start_conn(self):
        try:
            # maxshared 允许的最大共享连接数,默认0/None表示所有连接都是专用的
            # 当线程关闭不再共享的连接时,它将返回到空闲连接池中,以便可以再次对其进行回收。
            # mincached 连接池中空闲连接的初始连接数,实验证明没啥用
            self.__pool = PooledDB(creator=pymysql,
                                   mincached=1, # mincached 连接池中空闲连接的初始连接数,但其实没用
                                   maxcached=4,  # 连接池中最大空闲连接数
                                   maxshared=3, #允许的最大共享连接数
                                   maxconnections=2,  # 允许的最大连接数
                                   blocking=False,  # 设置为true,则阻塞并等待直到连接数量减少,false默认情况下将报告错误。
                                   host=self.host,
                                   port=self.port,
                                   user=self.user,
                                   passwd=self.passwd,
                                   db=self.db_name,
                                   charset=self.charset
                                   )
            print("0 start_conn连接数:%s " % (self.__pool._connections))
            self.conn = self.__pool.connection()
            print('connect success')
            print("1 start_conn连接数:%s " % (self.__pool._connections))

            self.conn2 = self.__pool.connection()
            print("2 start_conn连接数:%s " % (self.__pool._connections))
            db3 = self.__pool.connection()
            print("3 start_conn连接数:%s " % (self.__pool._connections))
            db4 = self.__pool.connection()
            print("4 start_conn连接数:%s " % (self.__pool._connections))
            db5 = self.__pool.connection()
            print("5 start_conn连接数:%s " % (self.__pool._connections))
            # self.conn.close()
            print("6 start_conn连接数:%s " % (self.__pool._connections))
            return True
        except:
            print('connect failed')
            return False

0 start_conn número de conexión: 0
conexión exitosa
1 start_conn número de conexión: 1
2 start_conn número de conexión: 2
3 start_conn número de conexión: 3
4 start_conn número de conexión: 4
conexión fallida

De acuerdo con el procedimiento anterior, puede comparar los resultados de la prueba para comprender los parámetros anteriores en detalle.

  • Mincached es de hecho inútil.Después de generar y salir del objeto pooledDB, no hay conexiones de inicialización mincached.
  • maxconnections = max(maxcached,maxshared), según los resultados de la comparación, el número máximo de conexiones es obviamente igual al mayor de maxcached y maxshared 4, por lo que se pueden abrir cuatro conexiones seguidas, pero la conexión falla cuando la quinta es alcanzado.
  • Si cambia el bloqueo a Verdadero, el "fallo de conexión" en la última línea del resultado del experimento no aparecerá, y el programa siempre estará bloqueado esperando que aparezca una nueva conexión inactiva. En este ejemplo, si no hay ninguna operación para cierre la conexión original, el programa siempre estará bloqueado y esperará.

Referencias

La información del sitio web oficial de DBUtils
lo lleva al grupo de conexiones de la base de datos

Supongo que te gusta

Origin blog.csdn.net/qq_23590921/article/details/117321019
Recomendado
Clasificación