Mark, I would always do a "select for update" in code like that.
Your code also seems a little wonky, in that you apparently have a
queue of rows, but when an item is complete rather than doing the
normal thing and updating a "done_p" flag column, you're deleting it
from the table. Hard to say withou knowing more about your
application, but that's also probably a problem. Unless I had a very
good reason to do otherwise, I would probably update the row, not
delete it; then if necessary run a sweeper job at some later point to
archive or delete out old obsolete completed rows.