It is especially useful when:
- An operation must not persist in the database.
- You are manually handling exceptions or validations.
- External integrations fail and partial changes should be undone.
🔧 Technical Definition
- cr is the database cursor.
- rollback() tells PostgreSQL to discard all changes since the last commit.
⚠️ Important Notes
- It does not raise an exception — it silently rolls back.
- Use with caution, as it rolls back the entire transaction, including unrelated changes in the current request lifecycle.
📌 Realistic Odoo Example
🎯Scenario: External API Fails :
You are pushing an invoice to a third-party service. If the API call fails, you rollback the transaction so nothing is saved in Odoo either.
class AccountMove(models.Model):
_inherit = ‘account.move‘
def action_post(self):
res = super().action_post()
for invoice in self:
try:
# Call external API
response = requests.post(‘https://api.example.com’, json={
‘invoice_number‘: invoice.name,
‘amount‘: invoice.amount_total
})
if response.status_code != 200:
raise Exception(“Failed to sync with external system.”)
except Exception as e:
_logger.error(f”API Sync Failed: {str(e)}”)
self.env.cr.rollback() # Revert invoice posting
raise UserError(“Invoice sync failed. Transaction cancelled.”)
return res
- 🎯 In this example, if the external call fails, Odoo’s action_post() effect is undone using rollback().
🧠 When to Use
Use Case |
Use rollback()? |
| External API failed | ✅ Yes |
| Custom validations failed | ✅ Yes |
| Soft errors (no rollback needed) | ❌ No |
| Standard ORM logic | ❌ No (ORM handles rollback on error) |
❗️ Caution
- Don’t mix rollback() with ORM operations carelessly.
- Avoid in multi-record operations unless you intend to rollback everything.
✅ Summary Table
Feature |
Description |
| Purpose | Discard uncommitted DB changes |
| Scope | Entire current DB transaction |
| Use With | self.env.cr.rollback() |
| Typical Use Case | API failure, custom validations, external syncs |