By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,876 Members | 1,291 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,876 IT Pros & Developers. It's quick & easy.

parallel interpreter/db problem. transaction didn't fix.

P: n/a
mysql_query("START TRANSACTION", $link2);
$q2=mysql_query("SELECT pictures.pid AS pid
FROM pictures,counter
WHERE pictures.pid>counter.pid
LIMIT 1", $link2);
if ($row2=mysql_fetch_assoc($q2)) {
mysql_query("UPDATE counter SET pid=$row2[pid]", $link2);
$n=$row2['pid'];
} else { //reached end of table.
mysql_query("UPDATE counter SET pid=1", $link2);
$n=1;
}
mysql_free_result($q2);
mysql_query("COMMIT", $link2);

the transaction makes no difference in the outcome.
I've even tried locking the tables, but that only results in invalid
resource errors.
when this picture code is called twice in sequence, (2 separate
interpreters, possibly by separate processors), I get the same image. I
shouldn't be getting the same image twice. this is one of those
hair-pulling sessions.

Everything I've tried results either in no pictures at all (picture
placeholders) with both the same sizes due to errors, or with the same
pictures on the same page.

transactions, no transactions, using a counter is out of the question.
I don't understand what's even happening here. the transaction *should* fix
this! Am I missing something
Apr 23 '06 #1
Share this Question
Share on Google+
14 Replies


P: n/a
>mysql_query("START TRANSACTION", $link2);
$q2=mysql_query("SELECT pictures.pid AS pid
FROM pictures,counter
WHERE pictures.pid>counter.pid
LIMIT 1", $link2);
if ($row2=mysql_fetch_assoc($q2)) {
mysql_query("UPDATE counter SET pid=$row2[pid]", $link2);
$n=$row2['pid'];
} else { //reached end of table.
mysql_query("UPDATE counter SET pid=1", $link2);
$n=1;
}
mysql_free_result($q2);
mysql_query("COMMIT", $link2);
Check to see whether your queries WORK. If they do not work,
print out the query and the value of mysql_error(). (For actual
production code, log it somewhere the user won't see it).
the transaction makes no difference in the outcome.
The transaction may be counterproductive. For certain applications,
having uncommitted changes be NOT visible to other connections until
they are committed can bite you big time. One example of this is
the "last modified" timestamp being used to identify recently changed
stuff, to actually make the changes in the real world (e.g. create
mailboxes). When it can take a long time to commit a transaction,
the "last modified" date can go from months old to hours old without
ever having been only a few minutes old, fooling provisioning software
trying to see all the changes and not miss any.
I've even tried locking the tables, but that only results in invalid
resource errors.
Then find out why your query didn't work, and fix it (print
mysql_error() for the failing query). You need to lock ALL the
tables you're going to use, and if you use aliases, you may have
to lock them under the name of the alias.
when this picture code is called twice in sequence, (2 separate
interpreters, possibly by separate processors), I get the same image. I
shouldn't be getting the same image twice. this is one of those
hair-pulling sessions.

Everything I've tried results either in no pictures at all (picture
placeholders)
Please explain how that can happen in terms of the generated HTML.
Are you generating numbers for which there is no image file?
with both the same sizes due to errors, or with the same
pictures on the same page.

transactions, no transactions, using a counter is out of the question.
I don't understand what's even happening here. the transaction *should* fix
this! Am I missing something


Gordon L. Burditt
Apr 23 '06 #2

P: n/a

"Gordon Burditt" <go***********@burditt.org> wrote in message
news:12*************@corp.supernews.com...
mysql_query("START TRANSACTION", $link2);
$q2=mysql_query("SELECT pictures.pid AS pid
FROM pictures,counter
WHERE pictures.pid>counter.pid
LIMIT 1", $link2);
if ($row2=mysql_fetch_assoc($q2)) {
mysql_query("UPDATE counter SET pid=$row2[pid]", $link2);
$n=$row2['pid'];
} else { //reached end of table.
mysql_query("UPDATE counter SET pid=1", $link2);
$n=1;
}
mysql_free_result($q2);
mysql_query("COMMIT", $link2);
Check to see whether your queries WORK. If they do not work,
print out the query and the value of mysql_error(). (For actual
production code, log it somewhere the user won't see it).


well, adding the transaction didn't affect *anything*. so I'm thinking
wrong somewhere.
my guess was that instance B and instance A had both read the same value at
nearly the same time, UPDATEd with the same value as a result. a race
condition. I had *thought* a transaction would fix that, but obviously
there's something about transactions I don't understand. I couldn't get
table locking (counter READ) to work - it just gave me invalid resource
errors down the line on my queries. I've never used table locking in PHP
code before.
If I could get table locking going, maybe that would be the fix to my
problem.

the transaction makes no difference in the outcome.


The transaction may be counterproductive. For certain applications,
having uncommitted changes be NOT visible to other connections until
they are committed can bite you big time. One example of this is
the "last modified" timestamp being used to identify recently changed
stuff, to actually make the changes in the real world (e.g. create
mailboxes). When it can take a long time to commit a transaction,
the "last modified" date can go from months old to hours old without
ever having been only a few minutes old, fooling provisioning software
trying to see all the changes and not miss any.

Good to know. as far as I can tell, the updates are occurring.
I've even tried locking the tables, but that only results in invalid
resource errors.


Then find out why your query didn't work, and fix it (print
mysql_error() for the failing query). You need to lock ALL the
tables you're going to use, and if you use aliases, you may have
to lock them under the name of the alias.
when this picture code is called twice in sequence, (2 separate
interpreters, possibly by separate processors), I get the same image. I
shouldn't be getting the same image twice. this is one of those
hair-pulling sessions.

Everything I've tried results either in no pictures at all (picture
placeholders)


Please explain how that can happen in terms of the generated HTML.
Are you generating numbers for which there is no image file?
with both the same sizes due to errors, or with the same
pictures on the same page.

transactions, no transactions, using a counter is out of the question.
I don't understand what's even happening here. the transaction *should*
fix
this! Am I missing something


Gordon L. Burditt

Apr 24 '06 #3

P: n/a

"Jim Michaels" <NO***************@yahoo.com> wrote in message
news:4s********************@comcast.com...

"Gordon Burditt" <go***********@burditt.org> wrote in message
news:12*************@corp.supernews.com...
>mysql_query("START TRANSACTION", $link2);
$q2=mysql_query("SELECT pictures.pid AS pid
FROM pictures,counter
WHERE pictures.pid>counter.pid
LIMIT 1", $link2);
if ($row2=mysql_fetch_assoc($q2)) {
mysql_query("UPDATE counter SET pid=$row2[pid]", $link2);
$n=$row2['pid'];
} else { //reached end of table.
mysql_query("UPDATE counter SET pid=1", $link2);
$n=1;
}
mysql_free_result($q2);
mysql_query("COMMIT", $link2);
Check to see whether your queries WORK. If they do not work,
print out the query and the value of mysql_error(). (For actual
production code, log it somewhere the user won't see it).


well, adding the transaction didn't affect *anything*. so I'm thinking
wrong somewhere.
my guess was that instance B and instance A had both read the same value
at nearly the same time, UPDATEd with the same value as a result. a race
condition. I had *thought* a transaction would fix that, but obviously
there's something about transactions I don't understand. I couldn't get
table locking (counter READ) to work - it just gave me invalid resource
errors down the line on my queries. I've never used table locking in PHP
code before.
If I could get table locking going, maybe that would be the fix to my
problem.


nope. table locking didn't work either. :-( i'm out of ideas. PHP has no
access to the UNIX system-level-like getuuid() function that I can use in
place of a random number generator. that would have been perfect.

There must be some way of doing a wrapping counter that works like a web
counter (exclusive access at transaction time).


the transaction makes no difference in the outcome.


The transaction may be counterproductive. For certain applications,
having uncommitted changes be NOT visible to other connections until
they are committed can bite you big time. One example of this is
the "last modified" timestamp being used to identify recently changed
stuff, to actually make the changes in the real world (e.g. create
mailboxes). When it can take a long time to commit a transaction,
the "last modified" date can go from months old to hours old without
ever having been only a few minutes old, fooling provisioning software
trying to see all the changes and not miss any.

Good to know. as far as I can tell, the updates are occurring.
I've even tried locking the tables, but that only results in invalid
resource errors.


Then find out why your query didn't work, and fix it (print
mysql_error() for the failing query). You need to lock ALL the
tables you're going to use, and if you use aliases, you may have
to lock them under the name of the alias.
when this picture code is called twice in sequence, (2 separate
interpreters, possibly by separate processors), I get the same image. I
shouldn't be getting the same image twice. this is one of those
hair-pulling sessions.

Everything I've tried results either in no pictures at all (picture
placeholders)


Please explain how that can happen in terms of the generated HTML.
Are you generating numbers for which there is no image file?
with both the same sizes due to errors, or with the same
pictures on the same page.

transactions, no transactions, using a counter is out of the question.
I don't understand what's even happening here. the transaction *should*
fix
this! Am I missing something


Gordon L. Burditt


Apr 24 '06 #4

P: n/a

"Jim Michaels" <NO***************@yahoo.com> wrote in message
news:4s********************@comcast.com...

"Gordon Burditt" <go***********@burditt.org> wrote in message
news:12*************@corp.supernews.com...
>mysql_query("START TRANSACTION", $link2);
$q2=mysql_query("SELECT pictures.pid AS pid
FROM pictures,counter
WHERE pictures.pid>counter.pid
LIMIT 1", $link2);
if ($row2=mysql_fetch_assoc($q2)) {
mysql_query("UPDATE counter SET pid=$row2[pid]", $link2);
$n=$row2['pid'];
} else { //reached end of table.
mysql_query("UPDATE counter SET pid=1", $link2);
$n=1;
}
mysql_free_result($q2);
mysql_query("COMMIT", $link2);
Check to see whether your queries WORK. If they do not work,
print out the query and the value of mysql_error(). (For actual
production code, log it somewhere the user won't see it).


well, adding the transaction didn't affect *anything*. so I'm thinking
wrong somewhere.
my guess was that instance B and instance A had both read the same value
at nearly the same time, UPDATEd with the same value as a result. a race
condition. I had *thought* a transaction would fix that, but obviously
there's something about transactions I don't understand. I couldn't get
table locking (counter READ) to work - it just gave me invalid resource
errors down the line on my queries. I've never used table locking in PHP
code before.
If I could get table locking going, maybe that would be the fix to my
problem.


Oh yeah - I forgot. The PC's Timer (clock) is normally set to interrupt
18.2 times per second (18.2Hz). This is much slower than millisecond
resolution than PHP claims. Unless Linux sets the Timer to something else,
(unix normally wants something around 100Hz I think), the nice fast XEON
server boxes we have today with up to 8MB cache, combined with web server
cacheing, may be contributing to my problem. But then I'm guessing.
I guess I should stop yapping & learn.

My biggest question is what works. if I delete am image from the database,
that leaves a hole in it. I can't use a plain counter (unless I include
code to continually bump the counter until it reaches a valid pid valie)
that's why the WHERE pid>$currentpid.
I may have to try the counter method. UPDATE blah SET counter=counter+1
seems to be more atomic/exclusive (?) than my other methods. what's going
to bite me is when I need to wrap the counter back to 1 or skip to the next
valid value. I don't know how to lock other processes out of the table.
ideas?
would be nice if I could have a random number generator that worked.

I just realized how I can generate an image without having to turn the
entire PHP file into a monolith image generator.

and I can use the random number generator too.
it works!

If I have to use the other method, I am still curious how to make things
work, because I have an existing codebase that needs to be fixed, that sends
content-type headers.

the transaction makes no difference in the outcome.


The transaction may be counterproductive. For certain applications,
having uncommitted changes be NOT visible to other connections until
they are committed can bite you big time. One example of this is
the "last modified" timestamp being used to identify recently changed
stuff, to actually make the changes in the real world (e.g. create
mailboxes). When it can take a long time to commit a transaction,
the "last modified" date can go from months old to hours old without
ever having been only a few minutes old, fooling provisioning software
trying to see all the changes and not miss any.

Good to know. as far as I can tell, the updates are occurring.
I've even tried locking the tables, but that only results in invalid
resource errors.


Then find out why your query didn't work, and fix it (print
mysql_error() for the failing query). You need to lock ALL the
tables you're going to use, and if you use aliases, you may have
to lock them under the name of the alias.
when this picture code is called twice in sequence, (2 separate
interpreters, possibly by separate processors), I get the same image. I
shouldn't be getting the same image twice. this is one of those
hair-pulling sessions.

Everything I've tried results either in no pictures at all (picture
placeholders)


Please explain how that can happen in terms of the generated HTML.
Are you generating numbers for which there is no image file?
with both the same sizes due to errors, or with the same
pictures on the same page.

transactions, no transactions, using a counter is out of the question.
I don't understand what's even happening here. the transaction *should*
fix
this! Am I missing something


Gordon L. Burditt


Apr 24 '06 #5

P: n/a
> nope. table locking didn't work either. :-( i'm out of ideas. PHP has no
access to the UNIX system-level-like getuuid() function that I can use in
place of a random number generator. that would have been perfect.


Second time today I've suggest getmypid().

Apr 24 '06 #6

P: n/a
Jim Michaels wrote:


well, adding the transaction didn't affect *anything*. so I'm thinking
wrong somewhere.
my guess was that instance B and instance A had both read the same value at
nearly the same time, UPDATEd with the same value as a result. a race
condition. I had *thought* a transaction would fix that, but obviously
there's something about transactions I don't understand. I couldn't get
table locking (counter READ) to work - it just gave me invalid resource
errors down the line on my queries. I've never used table locking in PHP
code before.
If I could get table locking going, maybe that would be the fix to my
problem.


Invalid resource errors should never occur. They mean you're getting an error
on your queries - and not checking for them.

Always check the results of MySQL queries! NEVER ASSUME THEY WORK!

And when you do check the result, what do you get?

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Apr 24 '06 #7

P: n/a

"fletch" <ri****************@googlemail.com> wrote in message
news:11*********************@i39g2000cwa.googlegro ups.com...
nope. table locking didn't work either. :-( i'm out of ideas. PHP has
no
access to the UNIX system-level-like getuuid() function that I can use in
place of a random number generator. that would have been perfect.


Second time today I've suggest getmypid().


used getmypid(). I get (surprisingly) the same pictures on the page. I
don't understand this.

mt_srand(make_seed()+getmypid());

Was what I used. make_seed() returns a float. Why PHP manual recommended
such a function I am not sure.
maybe I should just use getmypid() alone? Is that what you're trying to
say?
Apr 25 '06 #8

P: n/a

"Jerry Stuckle" <js*******@attglobal.net> wrote in message
news:p_******************************@comcast.com. ..
Jim Michaels wrote:


well, adding the transaction didn't affect *anything*. so I'm thinking
wrong somewhere.
my guess was that instance B and instance A had both read the same value
at nearly the same time, UPDATEd with the same value as a result. a race
condition. I had *thought* a transaction would fix that, but obviously
there's something about transactions I don't understand. I couldn't get
table locking (counter READ) to work - it just gave me invalid resource
errors down the line on my queries. I've never used table locking in PHP
code before.
If I could get table locking going, maybe that would be the fix to my
problem.

Invalid resource errors should never occur. They mean you're getting an
error on your queries - and not checking for them.

Always check the results of MySQL queries! NEVER ASSUME THEY WORK!

And when you do check the result, what do you get?


checked the server error logs, figured out how to find & fix the errors and
actually get an error message. turned out the tables I had locked for READ
and later were trying to UPDATE (write) was the cause of the error, so I
needed a write lock. so I changed the LOCK TABLES to a write lock.
Then I got another error stating that the other tables down the line needed
to be locked too. (ugh) so I did. then things were fixed.
Sort of.
images were still duplicated. (not again!)
lock tables didn't do it for me. the only thing I can figure is that
*maybe* the write lock doesn't prevent reads to the table and I still have a
race condition.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================

Apr 25 '06 #9

P: n/a

"Jerry Stuckle" <js*******@attglobal.net> wrote in message
news:p_******************************@comcast.com. ..
Jim Michaels wrote:


well, adding the transaction didn't affect *anything*. so I'm thinking
wrong somewhere.
my guess was that instance B and instance A had both read the same value
at nearly the same time, UPDATEd with the same value as a result. a race
condition. I had *thought* a transaction would fix that, but obviously
there's something about transactions I don't understand. I couldn't get
table locking (counter READ) to work - it just gave me invalid resource
errors down the line on my queries. I've never used table locking in PHP
code before.
If I could get table locking going, maybe that would be the fix to my
problem.

Invalid resource errors should never occur. They mean you're getting an
error on your queries - and not checking for them.

Always check the results of MySQL queries! NEVER ASSUME THEY WORK!

And when you do check the result, what do you get?


Do you suppose my transaction tryout didn't work because I had a SELECT
directly after the COMMIT on the same connection? Should everything be
lumped together for everything to work properly? I am new to transactions.


--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================

Apr 25 '06 #10

P: n/a
Jim Michaels wrote:
"Jerry Stuckle" <js*******@attglobal.net> wrote in message
news:p_******************************@comcast.com. ..
Jim Michaels wrote:

well, adding the transaction didn't affect *anything*. so I'm thinking
wrong somewhere.
my guess was that instance B and instance A had both read the same value
at nearly the same time, UPDATEd with the same value as a result. a race
condition. I had *thought* a transaction would fix that, but obviously
there's something about transactions I don't understand. I couldn't get
table locking (counter READ) to work - it just gave me invalid resource
errors down the line on my queries. I've never used table locking in PHP
code before.
If I could get table locking going, maybe that would be the fix to my
problem.


Invalid resource errors should never occur. They mean you're getting an
error on your queries - and not checking for them.

Always check the results of MySQL queries! NEVER ASSUME THEY WORK!

And when you do check the result, what do you get?

Do you suppose my transaction tryout didn't work because I had a SELECT
directly after the COMMIT on the same connection? Should everything be
lumped together for everything to work properly? I am new to transactions.

Well, COMMIT ends the previous transaction, and the next operation starts a new
one. So it could be.

But I think you have other problems here. I'd suggest you display the value of
counter.pid after you've updated it. It may not be incrementing like you think
it is.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Apr 25 '06 #11

P: n/a

"fletch" <ri****************@googlemail.com> wrote in message
news:11*********************@i39g2000cwa.googlegro ups.com...
nope. table locking didn't work either. :-( i'm out of ideas. PHP has
no
access to the UNIX system-level-like getuuid() function that I can use in
place of a random number generator. that would have been perfect.


Second time today I've suggest getmypid().


just tried with getmypid alone in place of a random number generator. got 3
of the same image.
$n=getmypid() % ($row3['a']+1); // mod MAX(id)+1
if (0==$n) $n=1;
and always the same one when I refresh. this not be a very busy server.
This tells me the OS doesn't necesarily always increment the PID when it
assigns one.
OR, the interpreter isn't a new process.(!)..

If PHP is being loaded as an apache .SO (DLL) dynamically linked module
(likely) - would this explain why it's not getting a new pid? PHP wouldn't
be a new process. Apache would be the process instead of PHP. loading up a
new module like PHP would simply allocate RAM for the shared functions.
Apr 25 '06 #12

P: n/a
> If PHP is being loaded as an apache .SO (DLL) dynamically linked module
(likely) - would this explain why it's not getting a new pid? PHP wouldn't
be a new process. Apache would be the process instead of PHP. loading up a
new module like PHP would simply allocate RAM for the shared functions.


This makes sense, it wouldn't be true if PHP were running as CGI. I
felt that if the two requests were coming in simultaneously then they
would be dispatched to different apache child processes, giving
different pids. If they ended up with the same pid then they came in at
different times, because an apache child process will only do one
request at a time.

Let's crack this.

The root problem is that a script is being called twice to deliver two
different images. So somewhere you no doubt have something like,
<img src="/image.php" />

The problem is when you have many of these you get the same image.

But you presumably dont have this:

<img src="/image.php" />
<img src="/image.php" />

because then the first call to the image would cache the image, giving
you, well, exactly the same problem as you are having now. (Is this the
problem?).

So what you need is

<img scr="/image.php?some_unique_junk" />
<img scr="/image.php?some_other_unique_junk" />

Which potentially gives you a parameter you can throw into seed()

Now, you don't want the same unique junk for different images because
caching works across page loads, so you need to effectively alias the
images with another file name.

HTH

Apr 25 '06 #13

P: n/a

"fletch" <ri****************@googlemail.com> wrote in message
news:11**********************@i39g2000cwa.googlegr oups.com...
If PHP is being loaded as an apache .SO (DLL) dynamically linked module
(likely) - would this explain why it's not getting a new pid? PHP
wouldn't
be a new process. Apache would be the process instead of PHP. loading
up a
new module like PHP would simply allocate RAM for the shared functions.
This makes sense, it wouldn't be true if PHP were running as CGI. I
felt that if the two requests were coming in simultaneously then they
would be dispatched to different apache child processes, giving
different pids. If they ended up with the same pid then they came in at
different times, because an apache child process will only do one
request at a time.

Let's crack this.

The root problem is that a script is being called twice to deliver two
different images. So somewhere you no doubt have something like,
<img src="/image.php" />

The problem is when you have many of these you get the same image.

But you presumably dont have this:

<img src="/image.php" />
<img src="/image.php" />


that's what I've got. browser cache I guess (?). Well don't that beat all.
makes sense.

because then the first call to the image would cache the image, giving
you, well, exactly the same problem as you are having now. (Is this the
problem?).

So what you need is

<img scr="/image.php?some_unique_junk" />
<img scr="/image.php?some_other_unique_junk" />
hmm. which means it needs to be a javascript-generated random number for the
image to be different each time.
I get much more random results. took a bit of kickstart though. thanks.

Which potentially gives you a parameter you can throw into seed()

Now, you don't want the same unique junk for different images because
caching works across page loads, so you need to effectively alias the
images with another file name.

HTH

Apr 25 '06 #14

P: n/a
> hmm. which means it needs to be a javascript-generated random number for the
image to be different each time.
I get much more random results. took a bit of kickstart though. thanks.


You would like to be able to have the browser cache the images when the
random image reoccurs though, as that will reduce your bandwidth costs
and speed up the browsing experience.

Apr 26 '06 #15

This discussion thread is closed

Replies have been disabled for this discussion.