The usual upsert is a SELECT to see whether the row exists and then an INSERT or an UPDATE. That is two round trips, and between them another connection can insert the same row — so the pattern is also a race.
INSERT INTO daily_stats (day, product_id, views)
VALUES ('2015-06-30', 91, 1)
ON DUPLICATE KEY UPDATE views = views + 1;
It relies on a unique or primary key to detect the collision — without one it simply inserts every time, which is the usual reason it “does not work”. VALUES(col) inside the update clause refers to the value that would have been inserted, which avoids repeating an expression. Be aware that the auto-increment counter advances even when the statement updates rather than inserts.