Performing a global lock in a Python web application?
Basically, I have the following problem. There is a order processing
system which handles payments. In very rare circumstances, we end up with
double orders because while we query the credit card handler via the API,
if the user refreshes the page really quickly, the credit card processor
sometimes responds to both requests as "success" and we get two successful
"paid" events in the system.
So my idea was to implement a lock around the payment stuff (per order)
and if the lock is locked, tell the customer off (which would happen if
the customer refreshes the page very quickly - I think in our case it was
actually intentional).
So I thought about doing it with Redis and came up with this:
def _PaymentInterlock(object):
def __init__(self, pp):
self.key = GlobalKey('pay_ilk_%s'%pp._ident)
def lock(self):
self.key(1)
def unlock(self):
self.key.delete()
def try_lock(self):
result = self.key()
if result == 1:
return False
self.lock()
return True
The only problem with this is that the try_lock operation would not be
atomic (as opposed to a real compare and store operation), so technically,
two WSGI workers could get a key miss and then both lock the "lock"
causing the same sort of problem.
Are the any suggestions on how I would tackle this sort of a problem?
No comments:
Post a Comment