On Sat, Sep 28, 2013 at 10:09 AM, Stephan Beal <sgb...@googlemail.com>wrote:

> On Thu, Sep 26, 2013 at 5:31 PM, Dan Kennedy <danielk1...@gmail.com>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
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to