Use after_commit instead of active record callbacks to avoid unexpected errors
AR callbacks after_create/after_update/after_destroy to generate background job etc. are useful, but these callbacks are still wrapped in the database transaction, and you may probably get unexpected errors on production servers.
Before
It’s common to generate a background job to send emails like
You won’t see any issue in development, as local DB can commit fast. But in production server, db traffic might be massive, worker probably finish faster than transaction commit. e.g
- primary process
- worker process
- BEGIN
In this case, the worker process query the newly-created notification before the main process commits the transaction, it will raise NotFoundError, because transaction in worker process can’t read free information from the transaction in the main process.
Refactor
So we should tell ActiveRecord to generate notification worker after notification insertion transaction committed.
Now the transactions order becomes
- main process
- worker process
- BEGIN
Worker process won’t receive NotFoundErrors anymore. :)