|
Posted by Chris Smith on 03/06/05 16:27
Josh Whiting wrote:
> I've been trying to switch to MySQL-based session storage instead of the
> native PHP session storage. In doing so, I've run into a lot of code on
> the web that exhibits a serious flaw regarding concurrent requests from
> the same client. All the code I've seen has glossed over the need to
> lock the session for the duration of the request, e.g. not allow
> concurrent requests to use it until it has finished. PHP's native
> session handler correctly does this, but lots of MySQL-driven session
> code does not.
Neither do.
> Example timeline:
> 1. client sends a request
> 2. session data is loaded from the db
> 3. same client sends a request before the first one is finished (e.g.
> frames, tabbed browsing, slow server response times, etc)
> 4. session data is again loaded from the db
> 5. the first request changes some values in $_SESSION
> 6. the second request changes some values in $_SESSION
> 7. the first request writes the data to the db and exits
> 8. the second request writes it's data (over that written by the first
> request) and exits
>
> PHP's native handler solves this problem by forcing concurrent requests
> to wait for each other. The same thing needs to happen in a
> database-driven session handler.
No request should be blocking (i.e. wait for concurrent processes to
execute). This implies a poor understanding of transactional processing
from both yourself and PHP!
> 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).
Forget it - rethink how your application is architected.
> Folks using database sessions who do not deal with this scenario be
> warned! I'm surprised so much bad code is going around for this task...
Agree.
Some guidelines, from my experience of developing time-critical
transactional systems in .Net (100 transactions/second type load).
- You usually only store some kind of identification for a user in the
session - no other data. doing otherwise is dangerous as there are
multiple copies of data floating around uncontrolled. A session-id is
enough information to store. Don't use the session for storing data
willy nilly - it is for identifying the session only - nothing else.
Can't say that enough. Don't use it for shortcutting code.
- If you want a proper transactional system, there are two ways to
handle concurrency:
1. Block until the transaction is committed - no good for performance
and scalability as you spend more time waiting than doing.
2. Fail commit on change. A sample solution: For each row, add an INT
which is incremented every time the data is updated (or use TIMESTAMP in
MySQL if you have to use it). Read the value with the data and send it
every time the data is saved. If the value is the same when it is
recieved, then consistency can be guaranteed so update the row, else
rollback the transaction (and tell the user someone else changed it
before them - reload the view and give them an opportunity to update it
again). This requires a good understanding of the DBMS you are using
and the principles around ACID compliant databases.
I'd personally recomment PostgreSQL over MySQL as MySQL is not truly
atomic and can't do transactions database-side (no server-side
programming) which makes it about as scalable as a brick. Small
updates/reads yeah but nothing much more complicated.
Personally, no-one in the PHP/MySQL arena tends to understand these
concepts as the two technologies are rarely used for pushing data around
on big systems (this is generally Java/Postgres' domain).
I ONLY use PHP/MySQL for knocking up quick web apps to fart out content
- nothing serious because it's simply not suited.
Cheers,
Chris Smith
Ninja Labs
http://www.ninjalabs.co.uk/
Navigation:
[Reply to this message]
|