title: Rails transaction isn't acting atomic?
body: <p>I have an accounting system I wrote which follows standard dual-entry accounting practices.</p>
  
  <p>There is a feature of dual entry accounting called 'trial balance' where you can verify the entire system is correct because when you run it, it will always equal <code>0.00</code></p>
  
  <p>I have written tests and always run my trial balance when the system is 'stopped', but under write-heavy database load during seeding lots of records, I noticed my trial balance is WRONG about 1 out of 10 tries.</p>
  
  <p>When it's at rest (no inserts), its always correct at <code>0.00</code> however.</p>
  
  <p>When I insert transactions they're always in a transaction, like this:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>The fact it breaks under load makes me think I'm not understanding something vital about how Rails transactions work......</p>
  
  <p>What could be causing this?</p>
  
  <p>FWIW my trial balance function (<code>GeneralLedger.new(property).trial_balance</code>) executes the following pseodo-SQL (<strong>NOT</strong> in a transaction):</p>
  
  <pre><code>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'
  </code></pre>
  
  <p>I then add them together according to the Accounting Formula to arrive at 0.00:</p>
  
  <pre><code>  def trial_balance
      balance_category(:asset) - (balance_category(:liability) + balance_category(:equity) + balance_category(:income) - balance_category(:expense))
    end
  </code></pre>
  
  <p>The <code>balance_category</code> function is what triggers each SELECT for a total of 5 times, once for each category.</p>
  
  <p>Because its returning 0 it means it's somehow selecting when it's halfway inserted........... I have no idea how this is happening?</p>
  
  <p>I could understand if the creation of the journal entry/line item was not in a transaction and it was SELECTing halfway inserted rows, but it should only select from the entire group as a whole after the transaction ends?</p>