1

I store my session in database, because there are 5 different servers that need to share it.

My experience is, that session_start reads the session from the database, and it's written back to the database, when the execution of the php file is over.

Let's say initially the session content is ['data1' => 0, 'data2' => 0] and I have two ajax files: ajax1.php, that sets data1 to 1, and ajax2.php that sets data2 to 2.

They run simultaneously like this:
ajax1.php ----------------------
ajax2.php      -------------
(So ajax2 starts running later, but finishes earlier)

In the situation I presented above, the following happens respectively:

  1. ajax1 reads session from db: data1 == 0 and data2 == 0
  2. ajax2 reads session from db: data1 == 0 and data2 == 0
  3. ajax1 sets its "local" superglobal $_SESSION: data1 = 1
  4. ajax2 sets its "local" superglobal $_SESSION: data2 = 2
  5. ajax2 writes the session to the database ['data1' => 0, 'data2' => 2]
  6. ajax1 writes the session to the database ['data1' => 1, 'data2' => 0]

This results that after they run the session contains ['data1' => 1, 'data2' => 0] when ['data1' => 1, 'data2' => 2] would be expected.

This is my problem, I need help:

  • Has someone encountered the same situation?
  • Is it "normal" that this happens, or it's my implementation which must have a problem?
  • And of course, how should I deal with this situation?
  • All other experience, thoughts, materials are welcome.

Thank you.

3
  • I think that you can use NFS to store your session and read it across different servers (from the same NFS). Commented Aug 11, 2017 at 7:26
  • @CvetomirLazarov Not sure if NFS is working with file locks / session locks properly. Commented Aug 11, 2017 at 7:34
  • @DanFromGermany I guess that you are right. My bad :( Here is a good read: stackoverflow.com/questions/12552955/… Commented Aug 11, 2017 at 7:42

2 Answers 2

0

This is one of the reasons why HHVM for example is faster than PHP7 in some situations, because it does not lock session files.

Read this helpful Q/A:

PHP & Sessions: Is there any way to disable PHP session locking?

There always seems to be some kind of race condition.

It might be helpful to use session_write_close() as soon as you don't write anymore data.

The ultimate solution would be to write your own session handler and not use PHP internal session functions. Then you have the most control over sessions and locking.

Have a look at this comment on PHP.net which describes exactly your problem:

http://php.net/manual/en/function.session-set-save-handler.php#49630

You could also try to implement your MySQL session handler differently and add lock support.

Sign up to request clarification or add additional context in comments.

3 Comments

I'm not sure this is right, but I experience that there is no lock after I moved storing the session from file to DB. If there was, ajax2 would wait till ajax1 finishes with writing the session, wouldn't it?
@SteveGeorge The link you provided is the same as I posted. Default file based session handling WILL lock the files and therefore ajax2 would wait until ajax1 finishes. This does not apply when memcached or HHVM is used and I think it doesn't apply when oracle is used.
0

I would suggest that you dont write the entire session with each ajax, just the data you have changed. If ajax1 is dedicated to data1, then it should never touch data2 at all, and the same for ajax2 in regards to data1.

EDIT

Refactor the logic a bit. Store in $_SESSION only the info needed to find the info in a database, in Memcached or in a Redis layer. Use the session key, or some other unique identifier you put in $_SESSION to access data you manually write in another table or storage technology. Since its session data, its not meant to survive reboots and does not need to be written to disk on each server. I would recommend memcached begause its easy to use, and really really fast.

Example: See example architecture here

11 Comments

How would you implement this? PHP sessions simply serialize() $_SESSION and flush it to the storage. It does not distinct between single key value pairs in the session global.
@DanFromGermany Refactor the logic a bit. Store in session only the info needed to find the info in a database, in memcached or in a Redis layer. Use the session key, or some other unique identifier that gets stored in the session DB by PHP to access data you manually write in another table or storage technology. Since its session, I would recommend memcached.
Because of 5 different servers, the stored data in memcached should be shared, no?
@SteveGeorge Yes, the servers would all be talking to the memcached server.
@SteveGeorge See my added image
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.