Description
If I'm not mistaken, there is an alternative way to disallow concurrent updates of the same product that doesn't require going up an isolation level from the default "read committed". That way is to use version number increments in conjunction with the "UPDATE ... WHERE product.version = ..." query. If two transactions try to modify the same product, the second one waits for the first one to commit, executes the update, and returns with zero affected rows, because the product's version has already been incremented by the first transaction, at which point we roll back the second one in the app.
I believe it would benefit the reader to be pointed to this pattern, even if in a footnote. It's described as a "compare and set" way to prevent lost updates in the "Transactions" chapter of Kleppmann's "Designing Data-Intensive Applications". That chapter is a good source on transaction isolation to direct the reader at.