Code Quiz

Lost Update in Inventory Transaction

A read-modify-write transaction leaks a lost update under READ COMMITTED because it never locks the row.

Codejavascript
async function purchase(client, productId, qty) {
  await client.query('BEGIN');
  const { rows } = await client.query(
    'SELECT stock FROM products WHERE id = $1',
    [productId]
  );
  const current = rows[0].stock;
  if (current < qty) {
    await client.query('ROLLBACK');
    return false;
  }
  await client.query(
    'UPDATE products SET stock = $1 WHERE id = $2',
    [current - qty, productId]
  );
  await client.query('COMMIT');
  return true;
}

Two concurrent calls oversell the product. What is the bug and its fix?