Reputation: 12246
I was wondering what session_write_close()
does. I find the manual a little bit vague.
I have some pretty big SELECT
queries. Before those SELECT
queries I'm calling session_write_close()
, and after the queries I'm calling session_start()
again.
You might wonder why I do this, if I don't and an user is executing one of those SELECT
queries and aborts them (trying to opening another page for example), the user can't open the new page (or has to wait pretty long). I think because the script is waiting until the large query is done.
So my question(s):
What exactly does session_write_close()
do when calling it before a query?
Why doesn't the user have to wait (with session_write_close()
before the query) when opening a new page, when aborting the query?
Thanks in advance
Upvotes: 5
Views: 3852
Reputation: 522382
PHP's default session store is simply a file on the hard disk. I.e., the contents of $_SESSION
are simply dumped into a file on disk. When you call session_start
, that file is read and $_SESSION
is populated, when the script ends, $_SESSION
is written back to disk.
It's easy to get into a classic race condition here. If two requests come in in parallel, and two independent scripts read from the file, and then sometime later the two scripts write back to the file... which one wins? What will be the content of the file, and may there have been some data overwritten?
The solution to this is file locking. PHP acquires a lock on the session file, preventing anyone else from reading or writing to it until the lock is lifted. If two parallel scripts are trying to acquire a lock at the same time, one of them has to wait until the other is done. That's what you're seeing.
session_write_close
explicitly writes the $_SESSION
content to disk and relinquishes the lock.
Upvotes: 12
Reputation: 173642
I hope that the below graph helps to understand what goes on; we're talking about a session for the same user (i.e. same session id):
script a | lock | script b
---------------------+------+-----------------
start
open session <- | yes | start
do stuff
close session -> | yes | -> open session
do heavy queries | | do stuff
open session <- | yes | <- script ended
script ended -> | no |
Closing the session when you're not going to use it, be it for a while or until the script ends, makes it available for another script.
Note that once the other script has run the session data may have been altered.
Upvotes: 4