def _Acquire(self, lease_time): self.lock_token = thread.get_ident() sqlite_connection = self.store.cache.Get(self.subject) # We first check if there is a lock on the subject. # Next we set our lease time and lock_token as identification. with sqlite_connection: locked_until, stored_token = sqlite_connection.GetLock( self.subject) # This is currently locked by another thread. if locked_until and (time.time() * 1e6) < float(locked_until): raise data_store.DBSubjectLockError("Subject %s is locked" % self.subject) # Subject is not locked, we take a lease on it. self.expires = int((time.time() + lease_time) * 1e6) sqlite_connection.SetLock(self.subject, self.expires, self.lock_token) # TODO(user): This shouldn't really be necessary, and seems fragile. We # should be able to use an UPDATE WHERE lock_expiration < now inside a # transaction and check that we changed one row. # Check if the lock stuck. If the stored token is not ours # then probably someone was able to grab it before us. locked_until, stored_token = sqlite_connection.GetLock(self.subject) if stored_token != self.lock_token: raise data_store.DBSubjectLockError("Unable to lock subject %s" % self.subject) self.locked = True
def _Acquire(self, lease_time): self.lock_token = thread.get_ident() self.expires = int((time.time() + lease_time) * 1e6) # This single query will create a new entry if one doesn't exist, and update # the lock value if there is a lock but it's expired. The SELECT 1 # statement checks if there is a current lock. The select from dual is # essentially a way to get the numbers into the query conditional on there # not being an existing lock. query = ( "REPLACE INTO locks(lock_expiration, lock_owner, subject_hash) " "SELECT %s, %s, unhex(md5(%s)) FROM dual WHERE NOT EXISTS (SELECT 1 " "FROM locks WHERE subject_hash=unhex(md5(%s)) AND (lock_expiration > " "%s))") args = [ self.expires, self.lock_token, self.subject, self.subject, time.time() * 1e6 ] unused_results, rowcount = self.store.ExecuteQuery(query, args) # New row rowcount == 1, updating expired lock rowcount == 2. if rowcount == 0: raise data_store.DBSubjectLockError("Subject %s is locked" % self.subject) self.locked = True
def _Acquire(self, lease_time): self.expires = int((time.time() + lease_time) * 1e6) with self.store.lock: expires = self.store.transactions.get(self.subject) if expires and (time.time() * 1e6) < expires: raise data_store.DBSubjectLockError("Subject is locked") self.store.transactions[self.subject] = self.expires self.locked = True