Exercise 2: The Race Condition, and Why upsert() Avoids It — Possible Solution ==================================================================== THE EXACT RACE CONDITION IN THE SIBLING COURSE ------------------------------ The sibling course's lookup route first checks the cache with a SELECT, and only runs an INSERT if that check finds nothing. If two requests for the same never-before-seen barcode arrive close enough together, both can run their SELECT before either one has inserted anything — so both see "not cached yet" and both proceed to call Open Food Facts and then INSERT. The first INSERT succeeds. The second INSERT, for the same barcode, violates the barcode PRIMARY KEY constraint on barcode_cache and fails outright. WHY upsert() DOESN'T HAVE THE SAME PROBLEM ------------------------------ This course's route follows the identical check-first shape, so both concurrent requests still both see "not cached yet" at the check stage. The difference is what happens next: instead of a plain INSERT, this course calls upsert(), which is defined specifically as "create this row if it doesn't exist, otherwise update it." So when the first request's upsert() creates the row, the second request's upsert() for the same barcode simply updates the row that now exists, instead of crashing on a duplicate primary key. WHY THIS WORKS AS AN ANSWER ------------------------------ It correctly identifies that both versions still have the identical check-then-fetch shape, and it correctly explains that the real difference is entirely in the write step — a plain INSERT that can collide vs. an upsert() that's defined to handle exactly that collision gracefully — rather than describing this as some more general "Prisma is safer" claim with no specific mechanism named.