You must update 10,000 User records (setup) and 10,000 related Account records (non-setup) in response to a single button click, and both updates are genuinely required together. Doing both DMLs in one synchronous transaction throws a MixedDML exception. Which approach correctly resolves this while keeping both updates?
- A. Wrap the User DML in Database.update with allOrNone=false so partial success suppresses the MixedDML error
- B. Perform the Account DML synchronously and move the User DML into a @future method (or Queueable) so it runs in a separate transaction ✓
- C. Add 'without sharing' to the class so setup and non-setup objects share the same DML context
- D. Reorder the statements so the setup-object DML always executes before the non-setup DML in the same transaction
Correct answer: B. MixedDML is resolved by separating setup and non-setup DML into different transactions, typically by deferring one to an async @future or Queueable method.
Consider this Batch class:
```
global class Recalc implements Database.Batchable<sObject>, Database.Stateful {
global Integer total = 0;
global void execute(Database.BatchableContext bc, List<Account> scope){
total += scope.size();
// ... work ...
}
}
```
A batch of 1,000,000 records runs with scope size 200. Midway, execute() throws an unhandled exception in one chunk. What happens?
- A. The entire batch rolls back and total resets to 0 across all chunks
- B. Only the failing chunk's DML is rolled back; other chunks already committed remain committed, and total retains its accumulated value from successful chunks ✓
- C. The batch pauses and can be resumed from the exact failed record via Database.resume()
- D. All subsequent chunks are skipped and the batch is marked Completed with partial data
Correct answer: B. Each Batch execute() chunk is its own transaction, so a failure rolls back only that chunk while committed chunks persist and Database.Stateful preserves accumulated instance state.
In the Salesforce Order of Execution, a before-insert trigger sets Field_A, a Validation Rule references Field_A, a Flow (record-triggered, after-save) updates Field_B, and a Workflow field update sets Field_C. Which sequence is correct for a single record insert?
- A. Validation Rule -> before trigger -> after trigger -> Workflow -> Flow
- B. before trigger -> Validation Rules -> after trigger -> after-save Flow -> Workflow field update -> (re-fire triggers if workflow updated a field) ✓
- C. Flow -> before trigger -> Validation Rule -> Workflow -> after trigger
- D. before trigger -> after trigger -> Validation Rule -> Workflow -> Flow (Flow always runs last, after commit)
Correct answer: B. Before triggers run first, then system+custom validation, then after triggers, then after-save flows, then workflow rules whose field updates can re-fire before/after triggers a second time.
A recursion-prevention pattern uses a static Boolean flag set to true on first trigger entry and never reset. Within a single transaction, a legitimate later update to those same records needs the trigger logic to run again. What is the risk of this exact static-flag design?
- A. Static flags reset between batch execute() chunks, so recursion is never actually prevented at scale
- B. A never-reset static flag can over-suppress legitimate re-entry, silently skipping trigger logic for records that genuinely need reprocessing within the same transaction ✓
- C. Static variables are shared across concurrent user sessions, causing one user's flag to block another's trigger
- D. The trigger depth limit of 16 makes static flags redundant, so the flag has no effect at all
Correct answer: B. A static flag that is set once and never reset blocks all subsequent legitimate re-entry in the same transaction, over-suppressing valid reprocessing rather than just breaking the recursive loop.
You have a SOQL query `SELECT Id FROM Contact WHERE Custom_Status__c = 'Active'` running against 8 million Contacts. It throws a non-selective query error in a trigger. Custom_Status__c has only two possible values ('Active'/'Inactive') split roughly 50/50. Which action will make this query selective?
- A. Add a custom index on Custom_Status__c; the index makes any filtered field selective regardless of value distribution
- B. Nothing on that field alone will help because the low-cardinality filter matches ~4M rows, exceeding the selectivity threshold; add a selective, indexed, high-cardinality filter (e.g., a bounded date/Id range) ✓
- C. Wrap the query with WITH SECURITY_ENFORCED, which forces the optimizer to use a selective path
- D. Convert it to a skinny table query, which removes all selectivity thresholds
Correct answer: B. A filter matching ~50% of 8M rows can never be selective even if indexed, because it exceeds the optimizer's row thresholds; you need an additional high-cardinality selective filter.
An LWC uses `@wire(getContacts, { accountId: '$recordId' }) contacts;` against a `cacheable=true` Apex method. A separate LWC in the same app inserts a new Contact via imperative Apex. The wired list does not show the new Contact even after the insert succeeds. What is the correct fix?
- A. Set cacheable=false on getContacts so the wire always hits the server
- B. Call refreshApex(this.contacts) after the insert completes, passing the wired provisioned value to invalidate the client cache and re-fetch ✓
- C. Reassign this.recordId to itself to force the '$recordId' reactive parameter to re-trigger
- D. Move the query into connectedCallback with an imperative call, since @wire cannot display server data
Correct answer: B. refreshApex on the stored wired reference invalidates the Lightning Data Service cache for that cacheable method and re-provisions fresh data, unlike changing an unrelated reactive variable.
You must call an external REST API from a trigger's after-insert context to enrich 200 newly created Leads, and the API allows only one record per request. You also need to respect the external API's rate limits with sequential ordering. Which async design is BEST?
- A. Use a single @future(callout=true) method that loops 200 times issuing callouts, since @future runs asynchronously
- B. Use a Queueable that processes a bounded batch of records and chains to the next Queueable (System.enqueueJob in execute) to enforce sequential ordering and stay within callout limits per transaction ✓
- C. Call the API directly in the after-insert trigger; triggers permit callouts as long as they are wrapped in a try/catch
- D. Use a Scheduled Apex job firing every minute to poll for new Leads and process them in bulk
Correct answer: B. Queueable chaining gives sequential ordering, per-transaction callout budgets, and controlled throughput, whereas @future can't chain and is limited to callouts with no ordering guarantee.
A class declared `public with sharing` calls a helper method in a second class declared `public without sharing`. The helper runs a SOQL query returning records the running user cannot see via sharing rules. What data does the query return?
- A. Records are filtered by the calling class's 'with sharing', because sharing is inherited down the call stack
- B. The query in the 'without sharing' helper runs in system mode for sharing and returns all matching records regardless of the user's sharing access ✓
- C. A runtime exception is thrown because mixing with/without sharing in one call stack is disallowed
- D. Sharing is enforced only if the helper is 'inherited sharing'; 'without sharing' always throws an FLS error
Correct answer: B. Sharing enforcement is determined by the sharing keyword of the class where the SOQL executes, so a 'without sharing' helper ignores the caller's 'with sharing' and returns all rows.
Which Apex test correctly verifies a callout without making a real HTTP request AND asserts bulk behavior?
- A. Use Test.setMock(HttpCalloutMock.class, new MyMock()) before Test.startTest(), insert 200 records to trigger the callout logic, then assert results after Test.stopTest() ✓
- B. Use SeeAllData=true so the test hits the real endpoint with production credentials for realism
- C. Wrap the callout in Test.startTest()/stopTest() only; the platform auto-mocks any HTTP callout inside that block
- D. Insert one record and assert a 200 status code, since bulk paths behave identically to single-record paths
Correct answer: A. HttpCalloutMock registered via Test.setMock stubs the HTTP response, and inserting 200 records inside start/stopTest exercises the bulk/async path and forces async completion before assertions.
A Platform Event subscriber (Apex trigger on the event) processes high-volume events. During a spike, some events appear to be processed twice. Which statement about the delivery semantics is correct here?
- A. Platform Events guarantee exactly-once delivery, so duplicate processing indicates a code bug unrelated to the platform
- B. Platform Event subscribers get at-least-once delivery and can be re-delivered (e.g., after an unhandled exception or EventBus.RetryableException), so subscribers must be idempotent ✓
- C. Events are delivered in strict transactional lock-step with the publisher's commit, so a failed subscriber rolls back the publisher
- D. Replay IDs guarantee no event is ever delivered more than once as long as you store the last replay ID
Correct answer: B. Platform Event delivery is at-least-once with possible retries/redelivery, so subscribers must be written idempotently to tolerate duplicate processing.
In the Salesforce order of execution, when do custom validation rules run relative to before triggers?
- A. Validation rules run before all triggers
- B. Validation rules replace before triggers
- C. Validation rules run after before triggers ✓
- D. Validation rules run after after triggers
Correct answer: C. Before triggers execute first, then system and custom validation rules run before the record is saved.
What is the maximum number of @future method invocations allowed per Apex transaction?
Correct answer: A. A transaction can enqueue at most 50 @future method calls.
Which statement about Queueable vs @future Apex is correct?
- A. Future methods can be chained and accept sObjects
- B. Queueable supports job chaining and non-primitive parameters ✓
- C. Both run strictly synchronously
- D. Neither can perform callouts
Correct answer: B. Queueable can chain jobs and accept sObjects/complex types, unlike @future which only takes primitives.
What is the standard way to prevent a trigger from recursing infinitely?
- A. Add more SOQL queries
- B. Increase governor limits
- C. Use a before and after trigger together
- D. Use a static Boolean flag to guard re-entry ✓
Correct answer: D. A static variable persists across the transaction and lets the trigger skip re-execution after the first run.
What is the Apex heap size limit for a synchronous transaction?
- A. 6 MB ✓
- B. 12 MB
- C. 3 MB
- D. 1 MB
Correct answer: A. Synchronous Apex has a 6 MB heap limit; asynchronous Apex gets 12 MB.
What does the WITH SECURITY_ENFORCED clause in SOQL do?
- A. Locks records against concurrent edits
- B. Runs the query asynchronously
- C. Enforces field- and object-level security in the query ✓
- D. Bypasses sharing rules for the query
Correct answer: C. WITH SECURITY_ENFORCED throws an exception if the running user lacks read access to referenced fields/objects.
What do the 'with sharing' / 'without sharing' keywords on an Apex class control?
- A. Field-level security on every field
- B. Record-level access via sharing rules ✓
- C. The API version of the class
- D. Whether triggers fire in order
Correct answer: B. These keywords determine whether the class respects the running user's record-level sharing, not FLS.
Which statement correctly distinguishes Change Data Capture from Platform Events?
- A. Both can only be consumed inside Apex
- B. CDC is synchronous while platform events are not
- C. Platform events store data in objects permanently
- D. Change Data Capture auto-publishes on record changes; platform events are custom-defined messages ✓
Correct answer: D. CDC automatically emits change events for record modifications, whereas platform events are developer-defined and explicitly published.
What is the main advantage of using a SOQL for-loop (for (Account a : [SELECT ...]))?
- A. It retrieves records in batches of 200 to reduce heap usage ✓
- B. It bypasses the SOQL query limit
- C. It commits DML automatically
- D. It runs the query asynchronously
Correct answer: A. The SOQL for-loop processes query results in chunks of 200, keeping heap usage low for large result sets.
A Mixed DML Operation error occurs when a single transaction performs DML on which combination?
- A. Two triggers fire on the same object
- B. More than 100 SOQL queries run
- C. Setup and non-setup objects in the same transaction ✓
- D. A SOQL query returns over 50,000 rows
Correct answer: C. Mixing DML on setup objects (like User or Group) and non-setup objects in one transaction raises a Mixed DML error.
In the Apex trigger order of execution, when do custom validation rules run relative to before triggers?
- A. After before triggers, before the record is committed ✓
- B. Before any before triggers execute
- C. After all after triggers execute
- D. They never run in the same transaction as triggers
Correct answer: A. In the save order, before triggers fire first, then custom validation rules run before the record is saved.
What is the standard best practice to prevent unintended trigger recursion?
- A. Use a static Boolean flag in a helper class to block re-entry ✓
- B. Add more triggers on the same object
- C. Move all logic into @future methods
- D. Deactivate the trigger during runtime
Correct answer: A. A static variable persists across the transaction, letting you guard against re-executing trigger logic.
Which statement comparing Queueable Apex and @future methods is correct?
- A. Queueable supports job chaining and non-primitive (sObject) parameters ✓
- B. @future methods support chaining directly
- C. @future methods accept sObject parameters
- D. Queueable jobs cannot be monitored via job ID
Correct answer: A. Queueable accepts complex types and returns a job ID for chaining/monitoring, unlike @future.
Why must a SOQL filter on a large object use a selective, indexed field?
- A. To avoid a non-selective query error from a full table scan ✓
- B. To raise the org's governor limits
- C. To bypass the running user's sharing rules
- D. To reduce required test coverage
Correct answer: A. Salesforce throws a non-selective query exception when a query on a large object can't use an index efficiently.
What triggers a MIXED_DML_OPERATION error?
- A. Performing DML on setup and non-setup objects in the same transaction ✓
- B. Executing two insert statements consecutively
- C. Querying two different objects in one method
- D. Using an upsert statement
Correct answer: A. Setup objects (like User) and non-setup objects can't be modified in the same transaction without async separation.
How does Database.insert(records, false) handle a partial failure in a bulk operation?
- A. It commits the successful records and returns per-record Save Results ✓
- B. It rolls back the entire batch
- C. It throws immediately and stops on the first error
- D. It automatically retries all failed records
Correct answer: A. Passing allOrNone=false lets valid records save while returning individual success/error results for each.
Which mechanism grants record-level access programmatically at runtime?
- A. Apex managed sharing via share object rows ✓
- B. Assigning a profile
- C. Assigning a permission set
- D. Setting field-level security
Correct answer: A. Apex managed sharing inserts rows into an object's __Share table to grant record access programmatically.
Which is a genuine limitation of @future methods?
- A. They cannot return a value and cannot call another @future method ✓
- B. They can return values to the caller
- C. They can be chained without limits
- D. They accept sObjects as parameters
Correct answer: A. @future methods must be void, take only primitives/collections of primitives, and can't invoke other @future methods.
In LWC, how does a child component communicate an event up to its parent?
- A. It dispatches a CustomEvent that the parent listens for ✓
- B. It directly mutates the parent's properties
- C. It applies @api to the parent component
- D. It can only use a pub-sub library
Correct answer: A. Child-to-parent communication in LWC uses CustomEvent dispatch with the parent binding an event handler.
When a 'without sharing' class is invoked from a 'with sharing' class, how is sharing enforced?
- A. Code in the 'without sharing' class runs without sharing enforcement ✓
- B. Sharing is always inherited as 'with sharing' from the caller
- C. The call throws a sharing violation exception
- D. Field-level security is enforced instead of sharing
Correct answer: A. Sharing is determined by the class where the executing code is declared, so the inner class runs without sharing.