Я использую три экземпляра PostgreSQL с использованием репликации (1 главный, 2 подчиненных), к которым обращаются два отдельных сервера:
- Первый (неэкспонированный) сервер в основном выполняет итерации по каждой строке в конкретной таблицеи постоянно обновляет определенные столбцы (ресурсы) каждый тик (на основе скорости производства этих ресурсов) для каждого пользователя.
- Второй сервер - это общедоступный API, который предоставляет различные функции, такие как расходование определенного количества этих ресурсов.
Для доступа к данным и манипулирования ими я использую библиотеку ORM, которая позволяет мне писать код следующим образом:
const resources = await repository.findById(1337);
// some complex computation
resources.iron = computeNewIron(resources.iron);
await repository.save(resources);
Конечно, может случиться так, что API захочетвычесть определенное количество ресурсов прямо, когда сервер, обрабатывающий тики, пытается обновить количество ресурсов, которое может заставить любой из серверов принять определенное количество ресурсов, которое является неправильным, в основном ваша типичная аномалия UPDATE.
Моя проблема в том, что я не просто пишу«простой» атомарный запрос такой UPDATE table SET iron = iron + 42 WHERE id = :id
.Библиотека ORM внутренне использует прямое назначение, которое не ссылается на соответствующие столбцы самостоятельно, что приводит к чему-то похожему на UPDATE table SET iron = 123 WHERE id = :id
, где сумма была вычислена ранее.
Я могу только предположить, что можно предотвратитьупомянутая аномалия, если я использую написанные вручную запросы, которые увеличивают / уменьшают значения атомарно с помощью собственных ссылок.Я хотел бы знать, какие другие варианты могут облегчить проблему.Должен ли я обернуть мой SELECT / Computation / UPDATE в транзакции?Достаточно ли этого?