Added methods to create utilize a lock table for managing access to the database during a multi-threaded import. Currently, only MySQL is supported

This commit is contained in:
Chaz Littlejohn 2011-03-22 21:45:09 +00:00
parent 3c2fdaf53e
commit dd6ce46487
2 changed files with 57 additions and 0 deletions

View File

@ -273,6 +273,7 @@ class Database:
self.db_path = '' self.db_path = ''
gen = c.get_general_params() gen = c.get_general_params()
self.day_start = 0 self.day_start = 0
self._has_lock = False
if 'day_start' in gen: if 'day_start' in gen:
self.day_start = float(gen['day_start']) self.day_start = float(gen['day_start'])
@ -1719,6 +1720,34 @@ class Database:
# however the calling prog requires. Main aims: # however the calling prog requires. Main aims:
# - existing static routines from fpdb_simple just modified # - existing static routines from fpdb_simple just modified
def setThreadId(self, threadid):
self.threadId = threadid
def acquireLock(self, wait=True, retry_time=.01):
while not self._has_lock:
cursor = self.get_cursor()
cursor.execute(self.sql.query['selectLock'])
record = cursor.fetchall()
self.commit()
if not len(record):
cursor.execute(self.sql.query['switchLock'], (True, self.threadId))
self.commit()
self._has_lock = True
return True
else:
cursor.execute(self.sql.query['missedLock'], (1, self.threadId))
self.commit()
if not wait:
return False
sleep(retry_time)
def releaseLock(self):
if self._has_lock:
cursor = self.get_cursor()
num = cursor.execute(self.sql.query['switchLock'], (False, self.threadId))
self.commit()
self._has_lock = False
def lock_for_insert(self): def lock_for_insert(self):
"""Lock tables in MySQL to try to speed inserts up""" """Lock tables in MySQL to try to speed inserts up"""
try: try:

View File

@ -108,6 +108,15 @@ class Sql:
self.query['createSettingsTable'] = """CREATE TABLE Settings self.query['createSettingsTable'] = """CREATE TABLE Settings
(version INTEGER NOT NULL) """ (version INTEGER NOT NULL) """
################################
# Create InsertLock
################################
if db_server == 'mysql':
self.query['createLockTable'] = """CREATE TABLE InsertLock (
id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
locked BOOLEAN NOT NULL DEFAULT FALSE)
ENGINE=INNODB"""
################################ ################################
# Create RawHands (this table is all but identical with RawTourneys) # Create RawHands (this table is all but identical with RawTourneys)
################################ ################################
@ -4502,6 +4511,25 @@ class Sql:
elif db_server == 'sqlite': elif db_server == 'sqlite':
self.query['analyze'] = "analyze" self.query['analyze'] = "analyze"
if db_server == 'mysql':
self.query['selectLock'] = """
SELECT locked
FROM InsertLock
WHERE locked=True
LOCK IN SHARE MODE"""
if db_server == 'mysql':
self.query['switchLock'] = """
UPDATE InsertLock SET
locked=%s
WHERE id=%s"""
if db_server == 'mysql':
self.query['missedLock'] = """
UPDATE InsertLock SET
missed=missed+%s
WHERE id=%s"""
if db_server == 'mysql': if db_server == 'mysql':
self.query['lockForInsert'] = """ self.query['lockForInsert'] = """
lock tables Hands write, HandsPlayers write, HandsActions write, Players write lock tables Hands write, HandsPlayers write, HandsActions write, Players write