orm - Atomic conditional-update in Django -
so have 2 models:
class unit(models.model): name = models.charfield() class session(models.model): unit = models.foreignkey(unit) startdatetime = models.datetimefield() enddatetime = models.datetimefield()
users can book 'units' sessions start , end @ user-requested date/time. no unit can in use @ same time , i'd enforce ensuring no overlapping sessions per unit can booked. i'd 1 underlying query if possible, presumably guaranteeing atomicity of update?
i've come 2 approaches, neither of i'm happy with:
executing raw sql:
insert "myapp_session" user_id, unit_id, startdatetime, enddatetime select 6, 2, '2013-05-18 02:09:02', '2013-05-18 03:09:02' "myapp_session" not exists (select * "myapp_session" unit_id=2 , ("startdatetime" between '2013-05-18 02:09:02' , '2013-05-18 03:09:02' or "enddatetime" between '2013-05-18 02:09:02' , '2013-05-18 03:09:02'));
this should insert new session if there none booked overlap it. possible orm similar?
the other approach use select_for_update()
on unit, using lock.
unitlock = list(unit.select_for_update().filter(id=2)) # list() forces evaluation, should block others until have finished inserting session? overlappingsessions = session.objects.filter(startdatetime__range=[requestedstart, requestedend], enddatetime__range=[requestedstart, requestedend]) if not overlappingsessions.exists(): session.objects.create(unit=2, startdatetime=requestedstart, enddatetime=requestedend) # lock should freed view function returns
this locks 1 row in units table, other sessions other units can still added concurrently.
another related approach might add 'sessioninsertinprogress' field unit. assuming updated atomically, stop other concurrent processes continuing inserting session on unit while allowing sessions booked other units unimpeded.
Comments
Post a Comment