Toto je vlastnost izolace transakcí. Je o tom napsáno hodně a vřele bych doporučil přehled v Designing Data-Intensive Aplikace . Zjistil jsem, že je to nejužitečnější popis pro zlepšení mého osobního porozumění.
Výchozí úroveň postgresu je ČTĚTE SE ZÁVAZNĚNO což umožňuje každé z těchto souběžných transakcí vidět podobný (stav dostupných prostředků), i když by měly být závislé.
Jedním ze způsobů, jak to vyřešit, by bylo označit každou z těchto transakcí jako konzistenci "SERIALIZABLE".
To by mělo vynutit správnost vaší aplikace za cenu dostupnosti, tj. v tomto případě druhá transakce nebude moci upravit záznamy a bude zamítnuta, což by vyžadovalo opakování. Pro POC nebo aplikaci s nízkým provozem je to obvykle naprosto přijatelný první krok, protože si můžete zajistit správnost právě teď.
Také si myslím, že ve výše uvedené knize byl příklad toho, jak bankomat řeší dostupnost. Umožňují tento závodní stav a uživateli přečerpat, pokud se nemohou připojit k centralizované bance, ale omezují maximální výběr, aby se minimalizoval rádius výbuchu!
Dalším architektonickým způsobem, jak to vyřešit, je převést transakce do režimu offline a učinit je asynchronními, takže každá transakce vyvolaná uživatelem je publikována do fronty, a poté, když máte ve frontě jediného spotřebitele, přirozeně se vyhnete jakémukoli konfliktu. Kompromis je zde podobný, že je k dispozici pevná propustnost od jednoho pracovníka, ale pomáhá to vyřešit problém se správností právě teď :P
Uzamykání napříč počítači (jako použití redis napříč postgres/grpc) se nazývá distribuované zamykání a je o něm napsáno hodně https://martin.kleppmann.com/2016/02/08/how-to-do-distributed-locking.html