У меня есть система бухгалтерского учета, которую я написал, которая следует стандартным методам учета с двумя записями.
Существует функция двойного учета, которая называется «пробный баланс», где вы можете проверить правильность всей системы, потому что при запуске она всегда будет равна 0.00
Я написал тесты и всегда запускаю пробный баланс, когда система «остановлена», но при высокой нагрузке на базу данных во время заполнения большого количества записей я заметил, что мой пробный баланс НЕПРАВИЛЬНО составляет примерно 1 из 10 попыток.
Когда он в состоянии покоя (без вставок), он всегда корректен при 0.00
.
Когда я вставляю транзакции, они всегда в транзакции, например:
2000.times do |i|
ActiveRecord::Base.transaction do
puts "#{i} ==================================================================="
entry = JournalEntry.create!(description: 'Purchase mower on credit', user: user)
entry.line_items.create!(amount: Money.from_amount(1551.75).cents, account: property.accounts.find_by(name: 'Equipment'), side: :debit)
entry.line_items.create!(amount: Money.from_amount(1551.75).cents, account: property.accounts.find_by(name: 'Accounts Payable'), side: :credit)
end
end
Тот факт, что он ломается под нагрузкой, заставляет меня думать, что я не понимаю что-то важное о том, как работают транзакции Rails ......
Что может быть причиной этого?
FWIW моя функция пробного баланса (GeneralLedger.new(property).trial_balance
) выполняет следующий псевдо-SQL ( НЕ в транзакции):
SELECT sum(...) WHERE account = 'asset'
SELECT sum(...) WHERE account = 'liability'
SELECT sum(...) WHERE account = 'equity'
SELECT sum(...) WHERE account = 'income'
SELECT sum(...) WHERE account = 'expense'
Затем я складываю их вместе в соответствии с формулой учета, чтобы получить 0,00:
def trial_balance
balance_category(:asset) - (balance_category(:liability) + balance_category(:equity) + balance_category(:income) - balance_category(:expense))
end
Функция balance_category
- это то, что запускает каждый SELECT в общей сложности 5 раз, один раз для каждой категории.
Поскольку он возвращает 0, это означает, что он каким-то образом выбирает, когда он наполовину вставлен ........... Я понятия не имею, как это происходит?
Я мог бы понять, если создание записи / позиции в журнале не было в транзакции, и это было ВЫБОР наполовину вставленных строк, но он должен выбирать только из всей группы в целом после завершения транзакции?