views:

268

answers:

3

I did some search about this topic but found nothing valuable.

If I don't use PHP default session handler, there is no session lock at request level. So, I have to protect critical section by myself.

In Java, we have synchronized. In C#, we have lock.

In PHP, how to do that?

+1  A: 

Use semaphores for that.

Ignacio Vazquez-Abrams
+2  A: 

Since PHP scripts aren't multi-threaded, I don't believe critical-sections are relevant. I agree that you have a race condition because multiple instances are run in parallel, but a critical section won't solve your problem.

If you're using a file-based session handler, you can try a basic flock(). If using a database, you can try using the engine's own (preferably, row-level) locking mechanism. If using memcached, you can try implementing a distributed lock system.

You won't want to apply a lock too broadly. You'll want something as granular as possible (tied to the session ID, perhaps). If you attempt to serialize all session behavior, you'll introduce a massive bottleneck.

In the database world (and elsewhere), optimistic "locks" are often all you need. They involve a simple counter that is incremented. If the count is "off," (collision) the record isn't updated and you can re-fetch and apply your differences as appropriate. It's an UPDATE table WHERE count = lastcount type thing combined with retry. This often does the trick.

Of course, you can use file locking, SYSV semaphores (sparingly) and a variety of other methods to achieve this goal. Just remember, this sounds like a race condition, but it has nothing to do with threads.

Pestilence
Thanks for your response. I understand PHP doesn't have no threading model like Java and C#. But, in same cases, I do want one session object be accessed only by one request handling(in PHP, process or thread). So, you suggest not to serialize all session behavior. Small granularity of locking bring high performance, but I just doubt that it would make code complex. Simply locking session in request level (like default session handler) is stupid but simple.
Morgan Cheng
It is simple, for sure, but it's a tad lazy. Why not lock per session-ID? On a single server or sharded cloud, you could easily lock on some `/tmp/XXX` file for each session. That would practically solve your problem.
Pestilence
A: 

Most of the times you don't have to deal with critical section, because PHP does not have a thread-model(no sharing of memory). I don't even think semephores is available to you. PHP uses a "Share-nothing Architecture" as you can see on of the slides of PHP creator Rasmus Lerdorf. This means as you can see on the slide that

Shared data is pushed down to the data-store layer

With just a simple PHP script running on top of apache you don't even have to deal with critical sections. you have to interact with data via your database. You could also use files and lock them, but I would go with database instead of files.

Hope this answers your question a little bit.

Alfred
Even though PHP is share-nothing-architecture, session variables are shared by multiple request. There is still possible critical section.
Morgan Cheng
Session are shared between multiple requests I guess, but they are safe standard? How can you get race conditions?
Alfred