mytoolkit/mymanager.py
changeset 18 a9e12b7cc207
parent 16 cb7e13711a99
child 39 0cef3540b69f
equal deleted inserted replaced
17:f768a3529ee7 18:a9e12b7cc207
    65 the connection is returned to the pool or closed (depending on number of connections
    65 the connection is returned to the pool or closed (depending on number of connections
    66 in pool and on setting of keep_open parameter).
    66 in pool and on setting of keep_open parameter).
    67 
    67 
    68 The row returned by fetchone_dict() is special dict object, which can be accessed
    68 The row returned by fetchone_dict() is special dict object, which can be accessed
    69 using item or attribute access, that is row['now'] or row.now.
    69 using item or attribute access, that is row['now'] or row.now.
       
    70 
    70 """
    71 """
    71 
    72 
    72 from contextlib import contextmanager
    73 from contextlib import contextmanager
    73 import logging
    74 import logging
    74 import threading
    75 import threading
    75 import select
       
    76 import socket
       
    77 
    76 
    78 import MySQLdb
    77 import MySQLdb
    79 import MySQLdb.cursors
    78 import MySQLdb.cursors
    80 
    79 
    81 from MySQLdb import DatabaseError, IntegrityError, OperationalError
    80 from MySQLdb import DatabaseError, IntegrityError, OperationalError
   197                 raise MyManagerError("Connection name '%s' not registered." % name)
   196                 raise MyManagerError("Connection name '%s' not registered." % name)
   198 
   197 
   199             conn = None
   198             conn = None
   200             while len(self.conn_pool[name]) and conn is None:
   199             while len(self.conn_pool[name]) and conn is None:
   201                 conn = self.conn_pool[name].pop()
   200                 conn = self.conn_pool[name].pop()
   202                 if conn.closed:
   201                 try:
       
   202                     conn.ping()
       
   203                 except MySQLdb.MySQLError:
       
   204                     conn.close()
   203                     conn = None
   205                     conn = None
   204 
   206 
   205             if conn is None:
   207             if conn is None:
   206                 ci = self.conn_known[name]
   208                 ci = self.conn_known[name]
   207                 conn = self._connect(ci)
   209                 conn = self._connect(ci)
   224             if len(self.conn_pool[name]) >= self.conn_known[name].keep_open:
   226             if len(self.conn_pool[name]) >= self.conn_known[name].keep_open:
   225                 conn.close()
   227                 conn.close()
   226                 return
   228                 return
   227 
   229 
   228             # connection returned to the pool must not be in transaction
   230             # connection returned to the pool must not be in transaction
   229             conn.rollback()
   231             try:
       
   232                 conn.rollback()
       
   233             except OperationalError:
       
   234                 conn.close()
       
   235                 return
   230 
   236 
   231             self.conn_pool[name].append(conn)
   237             self.conn_pool[name].append(conn)
   232         finally:
   238         finally:
   233             self.lock.release()
   239             self.lock.release()
   234 
   240 
   251 
   257 
   252     def _connect(self, ci):
   258     def _connect(self, ci):
   253         conn = MySQLdb.connect(cursorclass=Cursor, **ci.parameters)
   259         conn = MySQLdb.connect(cursorclass=Cursor, **ci.parameters)
   254         if not ci.isolation_level is None:
   260         if not ci.isolation_level is None:
   255             if ci.isolation_level == 'AUTOCOMMIT':
   261             if ci.isolation_level == 'AUTOCOMMIT':
   256                 conn.autocommit()
   262                 conn.autocommit(True)
   257             else:
   263             else:
   258                 curs = conn.cursor()
   264                 curs = conn.cursor()
   259                 curs.execute('SET SESSION TRANSACTION ISOLATION LEVEL ' + ci.isolation_level)
   265                 curs.execute('SET SESSION TRANSACTION ISOLATION LEVEL ' + ci.isolation_level)
   260                 curs.close()
   266                 curs.close()
   261         if ci.init_statement:
   267         if ci.init_statement: