Close Menu
SalesforceCodex
    Facebook X (Twitter) Instagram
    Trending
    • Building a Dynamic Tree Grid in Lightning Web Component
    • 10 Salesforce Chrome Extensions to Boost Your Productivity
    • How to Build a Generic Modal Window in Lightning Web Component
    • Top 10 Salesforce Flow Features of Salesforce Summer ’25
    • Unlock the Power of Vibe Coding in Salesforce
    • How to Implement Dynamic Queueable Chaining in Salesforce Apex
    • How to Implement Basic Queueable Chaining in Salesforce Apex
    • How to Suppress PMD Warnings in Salesforce Apex
    Facebook X (Twitter) Instagram
    SalesforceCodex
    Subscribe
    Sunday, June 29
    • Home
    • Architecture
    • Salesforce
      • News
      • Apex
      • Integration
      • Books Testimonial
    • Questions
    • Certification
      • How to Prepare for Salesforce Integration Architect Exam
      • Certification Coupons
    • Integration Posts
    • Downloads
    • About Us
      • Privacy Policy
    SalesforceCodex
    Home»Salesforce»Apex»Avoid Batch Apex and Use Queueable Class

    Avoid Batch Apex and Use Queueable Class

    Dhanik Lal SahniBy Dhanik Lal SahniNovember 5, 2021Updated:June 11, 202313 Comments5 Mins Read
    Facebook Twitter Pinterest LinkedIn Tumblr Email
    Avoid Batch Apex and Use Queueable Class
    Share
    Facebook Twitter LinkedIn Pinterest Email

    Salesforce has four asynchronous apex ( Queueable Apex, Scheduled Apex, Batch Apex, Future Methods) to run code asynchronously to handle different need of business application. These apex is used for syncing data in two systems, handling longer jobs which will hit Salesforce Governor limits. These asynchronous apex can be used in different use case. This post is to explain where to avoid batch apex and use Queueable Class instead. Although there are lot of use cases where batch job is sufficient to handle processing.

    This post will explain how to handle callout issue You have uncommitted work pending. Please commit or rollback before calling out

    Use Case To Solve:

    We have around 30K+ account records of health care providers, we need to validate address of all records using address API (any API like SmartyStreet, Google Places, ZipCode ). After API call we need to update record with outcome of API call like address validation is successful or failed in ValidationStatus field. ValidationStatus is custom field in account object. All health care data are stored in account object.

    Solution:

    To solve this use case we can use batch apex which will handle 200 records (100 in case of callout in batch) in a single batch and batch job will be created for all records. As it will run in batch, we have to put some condition in batch SOQL so that it will not process same record again and again. So we can use query like

    Select id, ValidationStatus__c from Account where ValidationStatus__c=false

    This will only process record which is pending but there is another problem with this approach. As validation is not successful due to some reason that record will be pending and same records will be fetched in each job for process. This issue we can handle using adding another filter last modified date in SOQL

    Select id, ValidationStatus__c from Account where ValidationStatus__c=false and LastModifiedDate<>TODAY

    Using this batch it will solve issue of not processing same record again and again. We will face another problem after that is , if we want to re-process pending record or error records after correction, it will not re-process those record on same day.

    So what will be efficient solution for our use case. Can we use another asynchronous apex as we have lot of records to process? Yes, we have to use another asynchronous apex Queueable to handle this. We can query all pending records in one parent queueable class and then process records in another queueable class which will support callout. We will run chain of Queueable child class to process 100 records at once. Once 100 records are processed, start another queueable child job. This way we can call external system and make list of records to update before we start another job. This way we can avoid uncommitted work pending issue also.

    Uncommitted work pending issue throws when we are calling external system and then updating response in object, when system start processing next record, previous records is still pending for commit so we get that error. This issue will be address by below approach

    1. We will call external callout for reach record one by one
    2. We will not update records immediately, instead we will add all records in collection
    3. Once 99 records are processed, we will start new queueable job for processing another set of 99 records
    4. Before we start new batch, we will update all records for status update.

    Above approach will handle issue uncommitted work pending for commit issue.

    Let us see code for this solution

    Above queueable apex code is getting all records which need to process and passing all records to another child queueable class. As we are passing all records to child queueable class we don’t require to run this class multiple time. So if any error occurs for any records and we want to re-process those records, we can run this class once again after record correction.

    Let us see code for child queueable class which will process each record and also handle uncommitted code pending issue.

    AddressVerification class do external callout to Smarty Street address API. External callout code is available in another blog Generic Apex class for Calling External System. To store API detail, I have used named credential SmartyStreet which will store API url https://us-street.api.smartystreets.com/street-address , username and password.

    AddressValidationQueueable is child queueable class which will call AddressVerification class for each record and add those accounts in list. Once set of 99 records are processed, we will update those records and start new child queueable class to process next set of 99 records. We are also removing that record from list so that it will not process again.

    Why 99 records in one batch?

    As we can call only 100 records in one batch in asynchronous apex. I have used 99 records instead of 100 but you can use 100 as well.

    Reference:

    1. Generic Apex class for Calling External System
    2. Revisit Asynchronous Apex : Type and Usage
    3. Queueable Apex
    4. Smarty Street API

    Related Posts

    1. Handle Heap Size for Apex Code Optimization
    2. Enhance Apex Performance with Platform Caching
    3. Apex Trigger Code Optimization
    4. Optimize Code by Disabling Debug Mode
    5. Optimizing Salesforce Apex Code
    6. Optimizing Loop in Apex Code

    If you need more discussion on this topic, let us connect for discussing and implementing this pattern.

    address validation apex Apex logging Asynchronous apex batch apex batch job batch processing integration named credential Queueable smarty street api uncommitted work pending
    Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
    Previous ArticleHeatMap Chart In LWC
    Next Article Dynamic Record Page Creation using FieldSet
    Dhanik Lal Sahni
    • Website
    • Facebook
    • X (Twitter)

    With over 18 years of experience in web-based application development, I specialize in Salesforce technology and its ecosystem. My journey has equipped me with expertise in a diverse range of technologies including .NET, .NET Core, MS Dynamics CRM, Azure, Oracle, and SQL Server. I am dedicated to staying at the forefront of technological advancements and continuously researching new developments in the Salesforce realm. My focus remains on leveraging technology to create innovative solutions that drive business success.

    Related Posts

    By Dhanik Lal Sahni4 Mins Read

    Building a Dynamic Tree Grid in Lightning Web Component

    June 29, 2025
    By Dhanik Lal Sahni9 Mins Read

    10 Salesforce Chrome Extensions to Boost Your Productivity

    June 1, 2025
    By Dhanik Lal Sahni4 Mins Read

    How to Build a Generic Modal Window in Lightning Web Component

    May 26, 2025
    View 13 Comments

    13 Comments

    1. Pingback: Optimizing Salesforce Apex Code | SalesforceCodex

    2. Ronen on May 3, 2022 10:26 pm

      Hello thanks for a great solution,
      I tried this yesterday and it all works fine with above 200 records, suddenly I started to get this error
      Too many queueable jobs added to the queue: 2
      Any Idea why this happened ?
      TIA

      Reply
      • Dhanik Lal Sahni on May 6, 2022 6:44 am

        Hello Ronen,

        This error will come when you are creating many queueable parent jobs. We should create new queueable job from child queueable class like i have mentioned in AddressValidationQueueable.apxc lines #48-50. I am not creating new job from AddressValidationQueueableRunner, this is done in AddressValidationQueueable.

        Let me know if this is not working.

        Thank You,
        Dhanik

        Reply
    3. Pingback: Queueable Vs Batch Apex In Salesforce - Salesforce Codex - Stories

    4. C Wallace on July 22, 2022 2:23 am

      Question. Why call processTargets(accts) twice? Why not call if before the the If statement? Seems like an issue to concise coding. Unless I’m missing something?

      Reply
      • Dhanik Lal Sahni on July 23, 2022 7:13 pm

        Thank You, Wallace. It should be called only once before queuing a new job. I have updated the code.

        Regards
        Dhanik

        Reply
    5. Viraj on October 13, 2023 7:34 pm

      What if I only need to process 10 records at a tine?

      Reply
      • Dhanik Lal Sahni on October 13, 2023 9:40 pm

        Hello Viraj,
        Please check updated code. processTargets(accts) should be out from if loop.

        Thank You,
        Dhanik

        Reply
    6. Pingback: Boost Performance of Salesforce Service Cloud - Vagmine Cloud Solution

    7. Pingback: Queueable Vs Batch Apex In Salesforce

    8. Pingback: Ultimate Checklist for Efficiently Querying Large Data Sets

    9. Pingback: What are Skinny Tables? - SalesforceCodex

    10. Pingback: What is Light DOM - Salesforce Codex

    Leave A Reply Cancel Reply

    Ranked #1 SALESFORCE DEVELOPER BLOG BY SALESFORCEBEN.COM
    Featured on Top Salesforce Developer Blog By ApexHours
    Recent Posts
    • Building a Dynamic Tree Grid in Lightning Web Component
    • 10 Salesforce Chrome Extensions to Boost Your Productivity
    • How to Build a Generic Modal Window in Lightning Web Component
    • Top 10 Salesforce Flow Features of Salesforce Summer ’25
    • Unlock the Power of Vibe Coding in Salesforce
    Ranked in Top Salesforce Blog by feedspot.com
    RSS Recent Stories
    • Top 20 Salesforce Data Cloud Interview Questions & Answers for Admins June 5, 2025
    • How to Connect Excel to Salesforce to Manage Your Data and Metadata February 9, 2025
    • Difference Between With Security and Without Security in Apex January 2, 2025
    • Top Reasons to Love Salesforce Trailhead: A Comprehensive Guide December 5, 2024
    • How to Utilize Apex Properties in Salesforce November 3, 2024
    Archives
    Categories
    Tags
    apex (112) apex code best practice (8) apex rest (11) apex trigger best practices (4) architecture (22) Asynchronous apex (9) AWS (5) batch apex (9) batch processing (4) code optimization (8) custom metadata types (5) design principle (9) einstein (3) flow (15) future method (4) google (6) google api (4) integration (19) integration architecture (6) lighting (8) lightning (66) lightning-combobox (5) lightning-datatable (10) lightning component (32) Lightning web component (64) lwc (53) named credential (8) news (4) optimize apex code (4) Permission set (4) Queueable (9) rest api (23) S3 Server (4) salesforce (143) salesforce apex (48) salesforce api (4) salesforce api integration (5) salesforce bulk api (3) Salesforce Interview Question (4) salesforce news (5) salesforce question (5) solid (6) tooling api (5) Visual Studio Code (3) Winter 20 (8)

    Get our newsletter

    Want the latest from our blog straight to your inbox? Chucks us your detail and get mail when new post is published.
    * indicates required

    Facebook X (Twitter) Instagram Pinterest YouTube Tumblr LinkedIn Reddit Telegram
    © 2025 SalesforceCodex.com. Designed by Vagmine Cloud Solution.

    Type above and press Enter to search. Press Esc to cancel.

    Ad Blocker Enabled!
    Ad Blocker Enabled!
    Our website is made possible by displaying online advertisements to our visitors. Please support us by disabling your Ad Blocker.