Why not use SELECT FOR UPDATE?
SELECT FOR UPDATE acquires a row-level lock that blocks concurrent transactions. At 500 req/s, the lock contention would serialize all visitor lookups into a single-threaded bottleneck. The double-try pattern has zero contention: both concurrent writes succeed or one writes and the other reads. No waiting, no blocking.