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.