[FIX] remove the lock on database connections

[ADD] exported method check_connectivity
[REF] better logging of the Connection and ConnectionPool objects
[REF] use template0 as template when create new database

bzr revid: chs@tinyerp.com-20100120163913-5ftbs7e85lwqb1et
This commit is contained in:
Christophe Simonis
2010-01-20 17:39:13 +01:00
parent 5303dc2e92
commit fecc3a360d
2 changed files with 78 additions and 121 deletions
+15 -38
View File
@@ -119,7 +119,7 @@ class Cursor(object):
if self.sql_log:
now = mdt.now()
try:
params = params or None
res = self._obj.execute(query, params)
@@ -195,11 +195,11 @@ class Cursor(object):
def autocommit(self, on):
offlevel = [ISOLATION_LEVEL_READ_COMMITTED, ISOLATION_LEVEL_SERIALIZABLE][bool(self._serialized)]
self._cnx.set_isolation_level([offlevel, ISOLATION_LEVEL_AUTOCOMMIT][bool(on)])
@check
def commit(self):
return self._cnx.commit()
@check
def rollback(self):
return self._cnx.rollback()
@@ -228,16 +228,13 @@ class ConnectionPool(object):
self._lock = threading.Lock()
self._logger = netsvc.Logger()
def _log(self, msg):
#self._logger.notifyChannel('ConnectionPool', netsvc.LOG_INFO, msg)
pass
def _debug(self, msg):
#self._logger.notifyChannel('ConnectionPool', netsvc.LOG_DEBUG, msg)
pass
self._logger.notifyChannel('ConnectionPool', netsvc.LOG_DEBUG, msg)
#pass
@locked
def borrow(self, dsn):
self._log('Borrow connection to %s' % (dsn,))
self._debug('Borrow connection to %s' % (dsn,))
result = None
for i, (cnx, used) in enumerate(self._connections):
@@ -270,7 +267,7 @@ class ConnectionPool(object):
@locked
def give_back(self, connection):
self._log('Give back connection to %s' % (connection.dsn,))
self._debug('Give back connection to %s' % (connection.dsn,))
for i, (cnx, used) in enumerate(self._connections):
if cnx is connection:
self._connections.pop(i)
@@ -281,6 +278,7 @@ class ConnectionPool(object):
@locked
def close_all(self, dsn):
self._debug('Close all connections to %s' % (dsn,))
for i, (cnx, used) in tools.reverse_enumerate(self._connections):
if dsn_are_equals(cnx.dsn, dsn):
cnx.close()
@@ -288,37 +286,17 @@ class ConnectionPool(object):
class Connection(object):
__LOCKS = {}
def _debug(self, msg):
self._logger.notifyChannel('Connection', netsvc.LOG_DEBUG, msg)
def __init__(self, pool, dbname, unique=False):
def __init__(self, pool, dbname):
self.dbname = dbname
self._pool = pool
self._unique = unique
def __enter__(self):
if self._unique:
self.lock()
return self
def __exit__(self, exc_type, exc_value, traceback):
if self._unique:
self.release()
def lock(self):
if self.dbname not in self.__LOCKS:
self.__LOCKS[self.dbname] = threading.Lock()
self.__LOCKS[self.dbname].acquire()
def release(self):
close_db(self.dbname)
self.__LOCKS[self.dbname].release()
self._logger = netsvc.Logger()
def cursor(self, serialized=False):
if self._unique:
lock = self.__LOCKS.get(self.dbname, None)
if not (lock and lock.locked()):
netsvc.Logger().notifyChannel('Connection', netsvc.LOG_WARNING, 'Unprotected connection to %s' % (self.dbname,))
cursor_type = serialized and 'serialized ' or ''
self._debug('create %scursor to "%s"' % (cursor_type, self.dbname,))
return Cursor(self._pool, self.dbname, serialized=serialized)
def serialized_cursor(self):
@@ -354,8 +332,7 @@ def dsn_are_equals(first, second):
_Pool = ConnectionPool(int(tools.config['db_maxconn']))
def db_connect(db_name):
unique = db_name in ['template1', 'template0']
return Connection(_Pool, db_name, unique)
return Connection(_Pool, db_name)
def close_db(db_name):
_Pool.close_all(dsn(db_name))