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?