# Advanced trigger context and handler patterns

*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/advanced-trigger-context-and-handler-patterns*

Which trigger context variables exist in each event, how merge and undelete fire triggers, how addError blocks saves and deletes, and how a single trigger with a handler, bulk-safe code and Id-based recursion guards survives 200-record chunks.

- 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:**

> Demonstrate knowledge of the best practices for writing Apex triggers.

## What the exam expects

- Read trigger code and spot a context variable used in an event where it is null or read-only (`Trigger.new` in delete, `Trigger.newMap` in before insert, editing `Trigger.new` after save).
- Route logic to the exact event with `Trigger.operationType` instead of `isInsert` alone.
- Predict which triggers fire on merge and undelete, and where `MasterRecordId` is readable.
- Block a save or delete with `addError()` on the right collection.
- Apply the trigger standards: one trigger per object with handlers, bulk-safe SOQL and DML, asynchronous callouts, and recursion guards that work across 200-record chunks.

Key terms: **context variable** (an implicit `System.Trigger` member such as `new`, `oldMap` or `operationType`); **handler** (the class a trigger delegates to); **recursion guard** (state that stops logic re-running in one transaction); **chunk** (a 200-record batch that gets its own trigger invocation); **losing record** (a record deleted by a merge).

## Key facts

| Fact | Detail | Source |
|---|---|---|
| Trigger.new | Insert, update and undelete only; editable only in before triggers | [Trigger Context Variables](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_context_variables.htm) |
| Trigger.newMap | Before update, after insert, after update, after undelete | [Trigger Context Variables](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_context_variables.htm) |
| Trigger.old and oldMap | Update and delete only; always read-only | [Context Variable Considerations](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_context_variables_considerations.htm) |
| DML on trigger collections | Trigger.new and Trigger.old can't be used in DML | [Context Variable Considerations](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_context_variables_considerations.htm) |
| Merge | Delete events for losers, update events for the winner; no merge event | [Triggers and Merge Statements](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_merge_statements.htm) |
| MasterRecordId | Set on losing records only in after delete | [Triggers and Merge Statements](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_merge_statements.htm) |
| addError in delete triggers | Call it on Trigger.old records | [Trigger Exceptions](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_exceptions.htm) |
| Chunk size | Trigger invoked per 200-record batch; Trigger.size counts the batch only | [Trigger Context Variables](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_context_variables.htm) |
| Between Bulk API chunks | Limits reset; static variables don't | [Static Variables](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_static.htm) |
| DML statement limit | 150 per transaction | [Governor Limits](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm) |

## Check yourself

- Why does `Trigger.newMap` throw a NullPointerException in a before insert trigger?
- When can a trigger read a losing record's MasterRecordId?
- Why does a static Boolean guard skip records after the first 200 in a Bulk API load?
- Which collection do you call addError() on to block a delete?

## Sources

- [Trigger Context Variables](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_context_variables.htm)
- [Context Variable Considerations](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_context_variables_considerations.htm)
- [Triggers and Merge Statements](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_merge_statements.htm)
- [Trigger Exceptions](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_exceptions.htm)
- [Common Bulk Trigger Idioms](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_bulk_idioms.htm)
- [Trigger and Bulk Request Best Practices](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_bestpract.htm)
- [Triggers](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers.htm)
- [Static and Instance Methods, Variables, and Initialization Code](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_static.htm)
- [Execution Governors and Limits](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm)
- [Record-Triggered Automation Decision Guide](https://architect.salesforce.com/docs/architect/decision-guides/guide/record-triggered)
- [Operations That Don't Invoke Triggers](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_ignoring_operations.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
