For example suppose you send a newsletter to several thousand subscribers and you advertise "The first hundred to click on this link get a 10% discount". As an extreme example assume thousands of clicks arrive within a few seconds. What's the correct way of making sure that after exactly the 100th click things are locked so that there is no chance of 101 or 102 customers getting the "congratulations on getting the discount message"
3 Answers
You could create a lock file and flock($fp, LOCK_EX)
it to ensure only one (PHP) process can have it opened at the same time.
After locking the file successfully, you process the request and, when finished, flock($fp, LOCK_UN)
it.
$fp
is the file handle returned by fopen()
.
Of course you can also use mutexes for that, but they are not enabled by default in PHP.
Here's a flow "chart" for the flock solution:
- Open the lock file (can be simply an empty file)
- Lock the file. If another process already locked it, this call will block until the other lock is released
- Check if the user is still eligible to do whatever he wanted to do
- If yes/no, do something
- Unlock the file
- Close the file

- 310,957
- 84
- 592
- 636
-
17. Add code so that if your PHP crashes in step 3 or 4, you clean up the lock. Otherwise, no-one will be able to do anything. Locks are hard :-) – James Feb 10 '11 at 22:46
Have a table in which you write the responses as you get them. Then it's easy to check if a particular response was in the first 100 - just see if it's in the first 100 rows when sorted by the appropriate field.
Let MySQL do all the hard work of locking for you!

- 3,265
- 4
- 22
- 28
-
An auto increment PK + checking mysql_insert_id() <= 100 is a clever and very simple solution. – John Cartwright Feb 10 '11 at 22:45
You can have a BEFORE INSERT
trigger, pull an autoincrement from another table Can you access the auto increment value in MySQL within one statement? and abort if it's above 100.