Committer: gariev
[internal] Replace table locks by row locks in Fotobilder table "domainchalbuffer"U trunk/lib/FotoBilder/Auth/LiveJournal.pm
Modified: trunk/lib/FotoBilder/Auth/LiveJournal.pm =================================================================== --- trunk/lib/FotoBilder/Auth/LiveJournal.pm 2011-04-13 06:49:17 UTC (rev 1441) +++ trunk/lib/FotoBilder/Auth/LiveJournal.pm 2011-05-24 03:38:38 UTC (rev 1442) @@ -154,27 +154,34 @@ "AND timemade < UNIX_TIMESTAMP() - 60*15"); # now, see if we have at least one buffered challenge to return - $dbu->do("LOCK TABLES domainchalbuffer WRITE"); - my $ch = $dbu->selectrow_hashref(qq{ - SELECT challenge, resp FROM domainchalbuffer - WHERE userid=$u->{userid} LIMIT 1 - }); - if ($ch) { - # we got one, so delete it. - $dbu->do("DELETE FROM domainchalbuffer WHERE userid=$u->{userid} ". - "AND challenge=? AND resp=?", undef, - $ch->{'challenge'}, $ch->{'resp'}); + # warning: other processes may access table "domainchalbuffer" concurently + GET_CHALLENGE: + { + my $ch = $dbu->selectrow_hashref(qq{ + SELECT challenge, resp FROM domainchalbuffer + WHERE userid=$u->{userid} LIMIT 1 + }); + if ($ch) { + # we got one, so delete it. + my $is_deleted = $dbu->do("DELETE FROM domainchalbuffer WHERE userid=$u->{userid} ". + "AND challenge=? AND resp=?", undef, + $ch->{'challenge'}, $ch->{'resp'}); + if ($is_deleted) { + # if we just got a buffered one, put it in challenges table and return it + $dbu->do("INSERT INTO challenges (userid, timecreate, challenge, resp) ". + "VALUES (?,UNIX_TIMESTAMP(),?,?)", undef, $u->{'userid'}, $ch->{'challenge'}, + $ch->{'resp'}); + return $ch->{'challenge'}; + } else { + # if we can't delete, then other process did it before us + redo GET_CHALLENGE; + } + } else { + # no challenges left in domainchalbuffer table + last GET_CHALLENGE; + } } - $dbu->do("UNLOCK TABLES"); - # if we just got a buffered one, put it in challenges table and return it - if ($ch) { - $dbu->do("INSERT INTO challenges (userid, timecreate, challenge, resp) ". - "VALUES (?,UNIX_TIMESTAMP(),?,?)", undef, $u->{'userid'}, $ch->{'challenge'}, - $ch->{'resp'}); - return $ch->{'challenge'}; - } - # time to buffer a batch from the remote LJ server. we'll make # 20, since they're probably needing the challenges to upload # a bunch of pictures.