On Sat, Sep 28, 2013 at 10:09 AM, Stephan Beal <[email protected]>wrote:
> On Thu, Sep 26, 2013 at 5:31 PM, Dan Kennedy <[email protected]>wrote: > >> It does. Both open a write transaction on the database. In the\ >> parent posts case either would work. >> > > Follow-up: i implemented this yesterday and it seems to do the job nicely. > Actually triggering the race condition was always basically impossible with > our infrastructure, so i can't really _confirm_ that it's all doing the > right thing, but it seems to be just fine (or at least doesn't break > anything). It basically looks like: > Follow-up 2, since i coincidentally have that code opened... maybe this will help someone else... /* Part of gf_db_mutex(). */ $_DB_MUTEX_KLUDGE = NULL; /** Various bugs in MySQL's table locking mechanism make it useless for most of our purposes, so for cases where we must ensure that the db remains locked for the duration of a single request, we use a separate sqlite3 db whose _sole_ purpose is to act as a mutex. Calling this function will either block until the mutex is acquired or will throw an exception on error (e.g. it times out while waiting). This is currently (201310) only used for the 1-to-1 meeting calculations, to avoid a 1-in-a-million case which could lead to double bookings of the same time slot (in which case the 2nd one would overwrite the first). */ function gf_db_mutex(){ global $_DB_MUTEX_KLUDGE; /* Note that we use only one sqlite3 db for all sites, but that is just a simplification. We "should" use a different one for each site. However, we only use this mutex for the 1-to-1 meeting tools and those don't get enough traffic that this will ever make a difference. */ if(!$_DB_MUTEX_KLUDGE){ $fn = gf_get_common_file_path('mutex.sqlite3'); $_DB_MUTEX_KLUDGE = new PDO('sqlite:'.$fn, NULL, NULL, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION) ); $_DB_MUTEX_KLUDGE->exec("BEGIN EXCLUSIVE") /* Per a discussion the sqlite mailing list, BEGIN EXCLUSIVE is all we need to acquire/hold the lock. */; } return $_DB_MUTEX_KLUDGE; } /** Explicitly unlocks the mutex acquired by gf_db_mutex(). Not normally needed - the lock is released when the underlying PDO instance is freed when PHP shuts down. */ function gf_db_mutex_free(){ global $_DB_MUTEX_KLUDGE; if($_DB_MUTEX_KLUDGE){ $_DB_MUTEX_KLUDGE->exec("ROLLBACK"); $_DB_MUTEX_KLUDGE = NULL; } } that said, PHP's built-in flock() would probably be a better solution, but i won't get paid to reimplement it :/. -- ----- stephan beal http://wanderinghorse.net/home/stephan/ http://gplus.to/sgbeal _______________________________________________ sqlite-users mailing list [email protected] http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

