если проверка прошла, то обе выполнятся
Кто сказал что СУБД позволит выполнить обе транзакции с одними и теми же исходными данными?
Если обе транзакции начали исполняться параллельно, прочитали одни и те же данные, и пытаются их перезаписать, как СУБД будет себя вести? Позволит ли она вообще отработать обеим транзакциям? Или одна их них подождёт, пока не закончит работу другая? Вопрос гораздо интереснее, чем кажется. И, что самое главное, неглупые люди уже подумали над ним.
Очень хорошо подумали.
В доках постгреса написано ещё лучше.
Или лучше каждый раз пересчитыапть из истории?
Запаритесь пересчитывать, это не масштабируется, сложность расчёта будет всё время расти. Если считаете, что можете накосячить с текущим балансом - сделайте возможность его пересчёта согласно истории пополнений/трат. Это называется
денормализованными данными. Это один из тех случаев, когда оправдано применение хранимых процедур для актуализации таких данных. Т.е. вместо непосредственной записи одновременно и в историю пополнений/трат и в актуальный баланс прямо из приложения, вы вместо этого вызываете хранимую процедуру, которая атомарно как пишет новую операцию - это ваши основные данные - так и меняет нужным образом ваши денормализованные данные - т.е. ваш баланс. Заодно в этой же хранимке можно дополнительно проверить возможность списания. Это решение не очень хорошо масштабируется, и вообще хранимки это антипаттерн для современных модных-молодёжных распределённых приложений, но судя по вашим вопросам врядли вы отвечаете за разработку сервиса, где таких списаний десятки тысяч в секунду, так что вам хватит.
Вот на SO ещё предлагают много решений этой классической проблемы, ни одно из которых не является идеальным и лучшим для всех ситуаций.