Can data caching cause interference?
I'm writing a new engine for my PHP sites that features a data caching functionality. Now I'm wondering if interference between these scripts is possible. Consider the following example:
Let's say many users visit the photography related website and two o开发者_运维技巧f them run two scripts in almost exactly the same time.
Script 1 removes a user named 'FooBar' and all his photos from database.
Script 2 displays a photo nr 12345 (made by FooBar).
- (Script 1) check if user 'FooBar' exists. Store its ID inside a variable
$id
. - (Script 2) check if a photo nr 12345 exists. Store owner ID inside a variable
$owner
. - (Script 1)
query("DELETE FROM users WHERE id='$id' ");
- (Script 2)
query("SELECT name FROM users WHERE id='$owner' ");
//error here - (Script 1)
query("DELETE FROM photos WHERE owner='$id' ");
As we see, the script 2 detects that a photo exists but its owner is already removed.
The question is: Are PHP scripts being processed in order (so the presented scenario would be impossible)? If not, what can I do to prevent such errors when sending multiple queries in a single script?
Thank you so much.
Thank you for your answers. The presented scenerio is just an example and i know this can be done in a better way. So, when creating a large website, i must be constantly aware that data can be changed during runtime.
But this way, I simply cannot trust any information stored in a variable in php. How do you cope with this type of problems? Updating or fetching all data in one query?
the presented scenario is possible. The only thing i'd say you could do is code an error for this eventuality: As you show, the query 4 does not return a valid owner. Now you could do several things, of which these are just examples:
- return the ownername in a combined query so you can at least show the name if you found a picture's owner (in point 2.). If later on you want to show more, you'll just have to return that the owner does not excist (anymore). That's what happened (it got deleted in between loads), so even if it's a bit weird for the user, he'll have to deal with it :)
- Just show the error on point 4, a bit like the second part of the previous example. You've gotten a result very shortly, but then it was gone. So you return "could not load user" or something like that.
Indeed, the race condition is possible.
I will say that it strikes me as odd in the removal script to delete the user before his photos. If something craps out after the user deletion but before the photo deletion, then the db still has his orphaned photos. Typically, transactions (using a storage engine that supports them, like InnoDB) mitigate this issue.
As for the race condition itself, I believe that there are techniques that use row locking to prevent other processes from accessing them at the same time.
[If I get the chance to do some research, I'll fill out with more details. My brief research so far on 'mysql row locking' suggests that some engines actually implicitly lock any rows that are being affected by a transaction. But I confess to having no direct experience there.]
精彩评论