Re: warning & question about mysql sessions & concurrency

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Mar 16, 2005 at 06:59:43PM +0100, Marek Kilimajer wrote:
> >SO, does anyone have some code that uses MySQL to replace PHP's native
> >session storage that also correctly handles this concurrency problem? 
> >Ideally I'd like to see just a set of functions that can be used with 
> >sessions_set_save_handler() to transparently shift PHP's sessions to a 
> >database, but I'm not going to use the stuff I've found on the web or 
> >even in books (appendix D of O'Reilly's Web Database Applications with 
> >PHP & MySQL publishes code with this problem).

> 
> MySQL's InnoDB supports row-level locking. So row the right row in 
> session_start and release it in session_close function.

But mysql does not support nested transactions.  Locking the row means
that your entire script has to happen inside a single transaction. 
Since my application logic requires transactions as well, it would mean
using two separate connections to MySQL, one for the session transaction
and one for business transactions, and that means twice the connection
overhead.

> In MyISAM you can use application-level locking: GET_LOCK() and 
> RELEASE_LOCK() in session_start and session_close, respectively. 
> Parameter would be session id with some prefix.

AH!  GET_LOCK() - that would do the trick!  I didn't realize MySQL
supported locking mechanisms independent of transactions/tables etc.

> The problem is when you need to create session id - you must lock the 
> whole table to find unused session id and insert it into table.

Hmm... couldn't I just do an 'insert ignore' with the session id every
time to kick off the process? Then MySQL would handle checking for an
existing row and create an empty one if it didn't exist. A very stripped
down example:

To open a session:
1. insert ignore into sessions (id,content) values ($sess_id,'')
2. select get_lock('my_prefix_".$sess_id, 15)
3. if NULL returned then abort, otherwise lock is aquired OK
4. select * from sessions where id=$sess_id

Do stuff ...

To close it:
1. update sessions set content='...'
2. select release_lock("my_prefix_".$sess_id)

I don't have all the details covered yet but I think that is just 
what I needed.  Thanks!!

/Josh W

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux