Daan
Daan

Reputation: 12246

What does session_write_close do when calling it before a query?

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

Answers (2)

deceze
deceze

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

Ja͢ck
Ja͢ck

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

Related Questions