Seems logical. I do something similar for processing online orders. Your column with "a running counter" could be an auto_increment column that is also your primary key for the table. That means less work for you maintaining the data.
You can select the lowest number by sorting on that column and using the LIMIT clause in your selection, but you can't use boolean true/false. MySql will treat 0 as false and non-zero as true.
SELECT productID
FROM procducts
WHERE NOT completed
ORDER BY productID
LIMIT 1,1
You may still encounter mutliple attempts to retrieve the same row if more than one user views the second page before another row is processed. You might want to simply provided a link to 'Next Row'. When you get the request, find the next row as above, update the 'completed' to lock it down, then serve your web page.
This brings up another question. Your plan seems to assume that rows retrieved will be completed. That's won't necessarily be true in the real world. People get distracted, go to lunch, go home, etc. You might consider another scheme that would differentiate between rows being viewed and rows that have been completed. This could be done by adding another column to track rows that are currently being viewed, or by creating a table that would hold the productID of all rows currently being viewed and possibly a timestamp so you can tell how long the row has been viewed and a user id so you know who is viewing the row.
So what happens when a user retrieves a row, but the browser or the computer crashes before the required action can be performed? You could set a time limit on open rows. If a row is viewed for longer than that limit, release the product row by removing it from the 'being_viewed' table. You could do this as a scheduled job that runs every few minutes or as part of your Perl script that access the second page.
Now, when the user completes the task for the row, you'll need to verify that the person updating the product row is the same user who has the current view open before allowing the update as this scenario would allow two users to be viewing the same row at the same time.
You have a good start, but you probably need to spend a little more time analyzing what could happen and what could go wrong. One of my basic assumptions when developing applications adheres to Murphy's Law: If there is any possibility that something will go wrong, it will, and at the least opportune moment.
When using http stateless connections nothing is guaranteed to happen as you expect.
Good luck!