Wow this was a hard thing to track down. It turns out that if ActiveRecord models with after_commit hooks get created in a transactional (DatabaseCleaner.strategy = :transaction) example and then a non-transactional example runs, all the left over objects' after_commit hooks will fire on the first "COMMIT" of the non-transactional example. This is because DatabaseCleaner does not call rollback_transaction_records...
I had to manually add this as an after hook in RSpec:
ActiveRecord::Base.connection.send(:rollback_transaction_records, true)
Perhaps something like this could go around here in the code?
https://github.com/bmabey/database_cleaner/blob/master/lib/database_cleaner/active_record/transaction.rb#L19