diff --git a/product/CMFActivity/Activity/SQLBase.py b/product/CMFActivity/Activity/SQLBase.py index ca9c3f80d3ba850957a4eb7dc4bbd97f28f6683d..54efc110c835eb19412919e0e7c1f3c0f4cad662 100644 --- a/product/CMFActivity/Activity/SQLBase.py +++ b/product/CMFActivity/Activity/SQLBase.py @@ -26,6 +26,10 @@ # ############################################################################## +from _mysql_exceptions import OperationalError +from MySQLdb.constants import ER +from zLOG import LOG, INFO + class SQLBase: """ Define a set of common methods for SQL-based storage of activities. @@ -49,3 +53,20 @@ class SQLBase: if priority is None: priority = default return priority + + def _retryOnLockError(self, method, args=(), kw=None): + if kw is None: + kw = {} + while True: + try: + result = method(*args, **kw) + except OperationalError, value: + if isinstance(value, OperationalError) and \ + value[0] in (ER.LOCK_WAIT_TIMEOUT, ER.LOCK_DEADLOCK): + LOG('SQLBase', INFO, 'Got a lock error, retrying...') + else: + raise + else: + break + return result + diff --git a/product/CMFActivity/Activity/SQLDict.py b/product/CMFActivity/Activity/SQLDict.py index e55d05bd07bc67be3aedb4881b9fdda8483b0f58..8732ca15b2eea9f788f9594d25199ee1eafdb3f0 100644 --- a/product/CMFActivity/Activity/SQLDict.py +++ b/product/CMFActivity/Activity/SQLDict.py @@ -378,7 +378,7 @@ class SQLDict(RAMDict, SQLBase): delay_uid_list.append(uid) if len(deletable_uid_list): try: - activity_tool.SQLDict_delMessage(uid=deletable_uid_list) + self._retryOnLockError(activity_tool.SQLDict_delMessage, kw={'uid': deletable_uid_list}) except: LOG('SQLDict', ERROR, 'Failed to delete messages %r' % (deletable_uid_list, ), error=sys.exc_info()) else: diff --git a/product/CMFActivity/Activity/SQLQueue.py b/product/CMFActivity/Activity/SQLQueue.py index 4c9a0f90ab391f6dc77d382c0109c6b1c515bb60..dda0d2a604434d65d783df8ed7ea5d37e53aa294 100644 --- a/product/CMFActivity/Activity/SQLQueue.py +++ b/product/CMFActivity/Activity/SQLQueue.py @@ -226,7 +226,7 @@ class SQLQueue(RAMQueue, SQLBase): LOG('SQLQueue', TRACE, 'Freed message %r' % (uid, )) if len(deletable_uid_list): try: - activity_tool.SQLQueue_delMessage(uid=deletable_uid_list) + self._retryOnLockError(activity_tool.SQLQueue_delMessage, kw={'uid': deletable_uid_list}) except: LOG('SQLQueue', ERROR, 'Failed to delete messages %r' % (deletable_uid_list, ), error=sys.exc_info()) else: