You are here: Re: [PHP] warning & question about mysql sessions & concurrency « PHP « IT news, forums, messages
Re: [PHP] warning & question about mysql sessions & concurrency

Posted by Josh Whiting on 03/17/05 00:54

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

 

Navigation:

[Reply to this message]


Удаленная работа для программистов  •  Как заработать на Google AdSense  •  England, UK  •  статьи на английском  •  PHP MySQL CMS Apache Oscommerce  •  Online Business Knowledge Base  •  DVD MP3 AVI MP4 players codecs conversion help
Home  •  Search  •  Site Map  •  Set as Homepage  •  Add to Favourites

Copyright © 2005-2006 Powered by Custom PHP Programming

Сайт изготовлен в Студии Валентина Петручека
изготовление и поддержка веб-сайтов, разработка программного обеспечения, поисковая оптимизация