# Savepoints, partial success and custom exceptions

*Platform Developer II Study Guide · Process Automation, Logic, and Integration · Last updated October 16, 2026 · https://www.certifyforce.com/study-guide/platform-developer-ii/process-automation-logic-and-integration/savepoints-partial-success-and-custom-exceptions*

What Database.rollback does and doesn't revert, how to call out after a rollback, how allOrNone false retries and re-fires triggers, how to design and chain custom exceptions, and how to log errors that survive a rolled-back transaction.

- Certification: Salesforce Platform Developer II
- Exam section: Process Automation, Logic, and Integration
- Study guide: https://www.certifyforce.com/study-guide/platform-developer-ii

**Official exam objective:**

> Describe and use the Apex features available for error handling and maintaining transactional integrity.

## What the exam expects

- Predict the database and variable state after `Database.rollback()`: discarded DML, surviving static variables, Ids left on sObjects.
- Make a callout after rolling back, using `Database.releaseSavepoint()`.
- Choose `Database.insert(records, false)` to keep valid records and read failures from `SaveResult`, and explain why triggers re-fire on the retry.
- Design custom exceptions: naming, inherited constructors, chaining a cause, catching by parent type.
- Recognise what can't be caught (`LimitException`) and log errors so the log survives a rollback.

Key terms: **savepoint** (a marker of database state that later DML can be rolled back to); **allOrNone** (the Database-method flag; `true` by default, `false` allows partial success); **SaveResult** (the per-record result of a Database insert or update); **chained cause** (an exception passed to another exception's constructor); **Publish Immediately** (a platform event behaviour that publishes even if the transaction fails).

## Key facts

| Fact | Detail | Source |
|---|---|---|
| Static variables on rollback | Not reverted | [Transaction Control](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_transaction_control.htm) |
| Id after rollback | An sObject inserted after the savepoint keeps its Id; re-inserting it fails | [Transaction Control](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_transaction_control.htm) |
| Savepoint cost | setSavepoint and rollback count toward DML statements, not rows | [Transaction Control](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_transaction_control.htm) |
| Callout after rollback | From API 60.0, allowed once uncommitted DML is rolled back and savepoints are released | [Transaction Control](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_transaction_control.htm) |
| allOrNone default | true: one failure throws and saves nothing | [DML Statements vs. Database Class Methods](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_dml_database.htm) |
| Partial-save attempts | Up to three; limits reset each retry; triggers re-fire on the clean subset | [Bulk DML Exception Handling](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dml_bulk_exceptions.htm) |
| Custom exception name | Must end with "Exception" and extend Exception | [Create Custom Exceptions](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_exception_custom.htm) |
| LimitException | Can't be caught | [Exception Class and Built-In Exceptions](https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_classes_exception_methods.htm) |
| Synchronous SOQL limit | 100 queries per transaction | [Governor Limits](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm) |
| Publish Immediately | Default; published even if the transaction fails | [Define a Platform Event](https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_define_ui.htm) |

## Check yourself

- Why does inserting the same sObject variable again after a rollback fail?
- When does a partial-success insert run a trigger more than once?
- Which constructor chains a caught exception into a custom one?
- Why does a Publish Immediately platform event suit error logging?

## Sources

- [Transaction Control](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_transaction_control.htm)
- [Bulk DML Exception Handling](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dml_bulk_exceptions.htm)
- [DML Statements vs. Database Class Methods](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_dml_database.htm)
- [Create Custom Exceptions](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_exception_custom.htm)
- [Exception Class and Built-In Exceptions](https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_classes_exception_methods.htm)
- [Exception Handling Example](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_exception_trycatch_example.htm)
- [Trigger Exceptions](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_exceptions.htm)
- [Define a Platform Event](https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_define_ui.htm)
- [Triggers and Order of Execution](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_order_of_execution.htm)
- [Execution Governors and Limits](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm)

## About the full unit

The "Core concepts", "Exam traps" and "Worked scenario" sections of this unit, its 10 linked practice questions, and unlimited timed mock exams are included with the Platform Developer II pack (USD $19): https://www.certifyforce.com/practice-exams
