Commit d7067b8b authored by Vincent Pelletier's avatar Vincent Pelletier

Remove transaction and query locks. Since DB instances are stored in a...

Remove transaction and query locks. Since DB instances are stored in a volatile attributes on ZMySQLDA instances, they are bound to one thread at most, so it's not needed to handle concurent accesses, and removing them should induce a performance increase.
Remove a tabulation caracter.
Delete volatile attribute at transaction end (_finish and _abort) to avoid multiple threads from using the same connection - because of ZODB connection pooling.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@13629 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent e9821d76
...@@ -155,11 +155,7 @@ def int_or_long(s): ...@@ -155,11 +155,7 @@ def int_or_long(s):
try: return int(s) try: return int(s)
except: return long(s) except: return long(s)
"""Locking strategy: FINISH_OR_ABORT_CALLED_ID = '_v_finish_or_abort_called'
The minimum that must be done is a mutex around a query, store_result
sequence. When using transactions, the mutex must go around the
entire transaction."""
class DB(TM): class DB(TM):
...@@ -188,12 +184,9 @@ class DB(TM): ...@@ -188,12 +184,9 @@ class DB(TM):
_p_oid=_p_changed=_registered=None _p_oid=_p_changed=_registered=None
def __init__(self,connection): def __init__(self,connection):
from thread import allocate_lock
self.connection=connection self.connection=connection
self.kwargs = kwargs = self._parse_connection_string(connection) self.kwargs = kwargs = self._parse_connection_string(connection)
self.db=apply(self.Database_Connection, (), kwargs) self.db=apply(self.Database_Connection, (), kwargs)
LOG("ZMySQLDA", INFO, "Opened new connection %s: %s" \
% (self.db, connection))
transactional = self.db.server_capabilities & CLIENT.TRANSACTIONS transactional = self.db.server_capabilities & CLIENT.TRANSACTIONS
if self._try_transactions == '-': if self._try_transactions == '-':
transactional = 0 transactional = 0
...@@ -202,17 +195,12 @@ class DB(TM): ...@@ -202,17 +195,12 @@ class DB(TM):
self._use_TM = self._transactions = transactional self._use_TM = self._transactions = transactional
if self._mysql_lock: if self._mysql_lock:
self._use_TM = 1 self._use_TM = 1
if self._use_TM:
self._tlock = allocate_lock()
self._tthread = None
self._lock = allocate_lock()
def __del__(self): def close(self):
LOG("ZMySQLDA", INFO, "Closing connection %s: %s" \ if self.db is not None:
% (self.db, self.connection)) self.db.close()
self.db.close() self.db = None
self.db = None
def _parse_connection_string(self, connection): def _parse_connection_string(self, connection):
kwargs = {'conv': self.conv} kwargs = {'conv': self.conv}
items = split(connection) items = split(connection)
...@@ -254,12 +242,9 @@ class DB(TM): ...@@ -254,12 +242,9 @@ class DB(TM):
_care=('TABLE', 'VIEW')): _care=('TABLE', 'VIEW')):
r=[] r=[]
a=r.append a=r.append
self._lock.acquire() if 1:
try:
self.db.query("SHOW TABLES") self.db.query("SHOW TABLES")
result = self.db.store_result() result = self.db.store_result()
finally:
self._lock.release()
row = result.fetch_row(1) row = result.fetch_row(1)
while row: while row:
a({'TABLE_NAME': row[0][0], 'TABLE_TYPE': 'TABLE'}) a({'TABLE_NAME': row[0][0], 'TABLE_TYPE': 'TABLE'})
...@@ -269,13 +254,10 @@ class DB(TM): ...@@ -269,13 +254,10 @@ class DB(TM):
def columns(self, table_name): def columns(self, table_name):
from string import join from string import join
try: try:
try:
self._lock.acquire()
# Field, Type, Null, Key, Default, Extra # Field, Type, Null, Key, Default, Extra
if 1:
self.db.query('SHOW COLUMNS FROM %s' % table_name) self.db.query('SHOW COLUMNS FROM %s' % table_name)
c=self.db.store_result() c=self.db.store_result()
finally:
self._lock.release()
except: except:
return () return ()
r=[] r=[]
...@@ -321,8 +303,7 @@ class DB(TM): ...@@ -321,8 +303,7 @@ class DB(TM):
result=() result=()
db=self.db db=self.db
try: try:
try: if 1:
self._lock.acquire()
for qs in filter(None, map(strip,split(query_string, '\0'))): for qs in filter(None, map(strip,split(query_string, '\0'))):
qtype = upper(split(qs, None, 1)[0]) qtype = upper(split(qs, None, 1)[0])
if qtype == "SELECT" and max_rows: if qtype == "SELECT" and max_rows:
...@@ -340,13 +321,11 @@ class DB(TM): ...@@ -340,13 +321,11 @@ class DB(TM):
result=c.fetch_row(max_rows) result=c.fetch_row(max_rows)
else: else:
desc=None desc=None
finally:
self._lock.release()
except OperationalError, m: except OperationalError, m:
if m[0] not in hosed_connection: raise if m[0] not in hosed_connection: raise
# Hm. maybe the db is hosed. Let's restart it. # Hm. maybe the db is hosed. Let's restart it.
db=self.db=apply(self.Database_Connection, (), self.kwargs) db=self.db=apply(self.Database_Connection, (), self.kwargs)
return self.query(query_string, max_rows) return self.query(query_string, max_rows)
if desc is None: return (),() if desc is None: return (),()
...@@ -366,9 +345,6 @@ class DB(TM): ...@@ -366,9 +345,6 @@ class DB(TM):
def string_literal(self, s): return self.db.string_literal(s) def string_literal(self, s): return self.db.string_literal(s)
def _begin(self, *ignored): def _begin(self, *ignored):
from thread import get_ident
self._tlock.acquire()
self._tthread = get_ident()
try: try:
if self._transactions: if self._transactions:
self.db.query("BEGIN") self.db.query("BEGIN")
...@@ -379,13 +355,10 @@ class DB(TM): ...@@ -379,13 +355,10 @@ class DB(TM):
except: except:
LOG('ZMySQLDA', ERROR, "exception during _begin", LOG('ZMySQLDA', ERROR, "exception during _begin",
error=sys.exc_info()) error=sys.exc_info())
self._tlock.release()
raise raise
def _finish(self, *ignored): def _finish(self, *ignored):
from thread import get_ident if getattr(self, FINISH_OR_ABORT_CALLED_ID, False):
if not self._tlock.locked() or self._tthread != get_ident():
LOG('ZMySQLDA', INFO, "ignoring _finish")
return return
try: try:
try: try:
...@@ -400,12 +373,11 @@ class DB(TM): ...@@ -400,12 +373,11 @@ class DB(TM):
error=sys.exc_info()) error=sys.exc_info())
raise raise
finally: finally:
self._tlock.release() self._v_database_connection = None
setattr(self, FINISH_OR_ABORT_CALLED_ID, True)
def _abort(self, *ignored): def _abort(self, *ignored):
from thread import get_ident if getattr(self, FINISH_OR_ABORT_CALLED_ID, False):
if not self._tlock.locked() or self._tthread != get_ident():
LOG('ZMySQLDA', INFO, "ignoring _abort")
return return
try: try:
if self._mysql_lock: if self._mysql_lock:
...@@ -417,4 +389,5 @@ class DB(TM): ...@@ -417,4 +389,5 @@ class DB(TM):
else: else:
LOG('ZMySQLDA', ERROR, "aborting when non-transactional") LOG('ZMySQLDA', ERROR, "aborting when non-transactional")
finally: finally:
self._tlock.release() setattr(self, FINISH_OR_ABORT_CALLED_ID, True)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment