https://habr.com/en/company/postgrespro/blog/467437/ dá o seguinte exemplo de uma atualização perdida:
Por exemplo, duas transações vão aumentar o valor na mesma conta em ₽100 (₽ é o símbolo da moeda para o rublo russo). A primeira transação lê o valor atual (₽1000) e, em seguida, a segunda transação lê o mesmo valor. A primeira transação aumenta o valor (isso dá ₽1100) e grava esse valor. A segunda transação age da mesma forma: obtém o mesmo ₽1100 e escreve este valor. Como resultado, o cliente perdeu ₽100
Li isso algumas vezes. Mas não entendo como o cliente perdeu P100. Por favor explique.
Existem duas transações separadas (T1 e T2) que adicionam ₽100 ao saldo do cliente.
O resultado pretendido é:
Ou vice-versa (T2 depois T1). O ponto importante é que ambos os incrementos de ₽100 são aplicados.
No exemplo de uma atualização perdida, ocorre algo como o seguinte:
Dessa forma, o saldo final é de ₽1100, não de ₽1200, então o cliente perdeu ₽100.
Adicionando à resposta de @Paul White: o artigo para o qual você vincula está afirmando que há mais de um "nível" de "isolamento" de transação (pense em "força") e é importante saber com o que você está lidando em cada caso.
Quando encontrei transações pela primeira vez, presumi que eram tudo ou nada e funcionavam da maneira que eu ingenuamente esperava ou o banco de dados estava quebrado. Mas isso não é bem verdade: existem diferentes tipos de inconsistência que podem ser permitidas no padrão SQL 92
O artigo fornece uma visão geral decente de como são esses erros, para que você possa decidir se eles são um problema para o seu caso de uso. Se um erro específico não for um problema para seu aplicativo, pode fazer sentido permitir isso em troca de um desempenho mais alto do banco de dados.
Paul respondeu à sua pergunta direta - como funciona uma atualização perdida (e nunca é permitida no SQL 92). O artigo também mostra como ocorrem outros tipos de erro e os nomes dos níveis de isolamento que permitem esses erros.