[CalendarServer-changes] [7079] CalendarServer/trunk/txdav/common/datastore/sql.py
source_changes at macosforge.org
source_changes at macosforge.org
Thu Feb 24 12:21:48 PST 2011
Revision: 7079
http://trac.macosforge.org/projects/calendarserver/changeset/7079
Author: cdaboo at apple.com
Date: 2011-02-24 12:21:46 -0800 (Thu, 24 Feb 2011)
Log Message:
-----------
Use savepoints instead of lock on calendar_home table.
Modified Paths:
--------------
CalendarServer/trunk/txdav/common/datastore/sql.py
Modified: CalendarServer/trunk/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql.py 2011-02-24 18:06:02 UTC (rev 7078)
+++ CalendarServer/trunk/txdav/common/datastore/sql.py 2011-02-24 20:21:46 UTC (rev 7079)
@@ -470,31 +470,38 @@
else:
if not create:
returnValue(None)
- # Need to lock to prevent race condition
- # FIXME: this is an entire table lock - ideally we want a row lock
- # but the row does not exist yet. However, the "exclusive" mode does
- # allow concurrent reads so the only thing we block is other
- # attempts to provision a home, which is not too bad
+ # Use savepoint so we can do a partial rollback if there is a race condition
+ # where this row has already been inserted
+ savepoint = SavepointAction("homeWithUID")
+ yield savepoint.acquire(txn)
- # Also note that we must not cache the owner_uid->resource_id
- # mapping in _cacher when creating as we don't want that to appear
- # until AFTER the commit
-
- yield Lock(cls._homeSchema, 'exclusive').on(txn)
- # Now test again
- exists = yield cls._resourceIDFromOwnerQuery.on(txn, ownerUID=uid)
- if not exists:
+ try:
resourceid = (yield Insert(
{cls._homeSchema.OWNER_UID: uid},
Return=cls._homeSchema.RESOURCE_ID).on(txn))[0][0]
yield Insert(
{cls._homeMetaDataSchema.RESOURCE_ID: resourceid}).on(txn)
- home = cls(txn, uid, notifiers)
- home = (yield home.initFromStore(no_cache=not exists))
- if not exists:
+ except Exception: # FIXME: Really want to trap the pg.DatabaseError but in a non-DB specific manner
+ yield savepoint.rollback(txn)
+
+ # Retry the query - row may exist now, if not re-raise
+ homeObject = cls(txn, uid, notifiers)
+ homeObject = (yield homeObject.initFromStore())
+ if homeObject:
+ returnValue(homeObject)
+ else:
+ raise
+ else:
+ yield savepoint.release(txn)
+
+ # Note that we must not cache the owner_uid->resource_id
+ # mapping in _cacher when creating as we don't want that to appear
+ # until AFTER the commit
+ home = cls(txn, uid, notifiers)
+ home = (yield home.initFromStore(no_cache=True))
yield home.createdHome()
- returnValue(home)
+ returnValue(home)
@classmethod
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110224/b597acb1/attachment-0001.html>
More information about the calendarserver-changes
mailing list