When passing in a collection of sObjects to a Queueable what values are used?












3















Suppose I pass in a collection of sObjects to a queueable. Does the queueable execute on the values of the sobjects field that get passed when the queueable is invoked? Given it is possible for these field values to get modified by the synchronous call, is the Asynch Apex platform smart enough to account for that?










share|improve this question




















  • 1





    Please try to include obvious tags. When a question relates to [apex], it should be tagged as such.

    – Adrian Larson
    Jan 14 at 20:15
















3















Suppose I pass in a collection of sObjects to a queueable. Does the queueable execute on the values of the sobjects field that get passed when the queueable is invoked? Given it is possible for these field values to get modified by the synchronous call, is the Asynch Apex platform smart enough to account for that?










share|improve this question




















  • 1





    Please try to include obvious tags. When a question relates to [apex], it should be tagged as such.

    – Adrian Larson
    Jan 14 at 20:15














3












3








3








Suppose I pass in a collection of sObjects to a queueable. Does the queueable execute on the values of the sobjects field that get passed when the queueable is invoked? Given it is possible for these field values to get modified by the synchronous call, is the Asynch Apex platform smart enough to account for that?










share|improve this question
















Suppose I pass in a collection of sObjects to a queueable. Does the queueable execute on the values of the sobjects field that get passed when the queueable is invoked? Given it is possible for these field values to get modified by the synchronous call, is the Asynch Apex platform smart enough to account for that?







apex queueable-interface






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 14 at 20:15









Adrian Larson

106k19113240




106k19113240










asked Jan 14 at 20:13









user11235813user11235813

4,491547128




4,491547128








  • 1





    Please try to include obvious tags. When a question relates to [apex], it should be tagged as such.

    – Adrian Larson
    Jan 14 at 20:15














  • 1





    Please try to include obvious tags. When a question relates to [apex], it should be tagged as such.

    – Adrian Larson
    Jan 14 at 20:15








1




1





Please try to include obvious tags. When a question relates to [apex], it should be tagged as such.

– Adrian Larson
Jan 14 at 20:15





Please try to include obvious tags. When a question relates to [apex], it should be tagged as such.

– Adrian Larson
Jan 14 at 20:15










2 Answers
2






active

oldest

votes


















9














sObjects (and other objects, for that matter) that are instance variables in Queueables and in Batch Apex classes are serialized and stored, and then deserialized at the time the Asynchronous Apex is executed. Field values for sObjects are not refreshed unless your code performs an explicit SOQL query to do so.



Take this Queueable, for example:



public class TestQueueable implements Queueable {
private Account a;

public TestQueueable(Account a) {
this.a = a;
}

public void execute(System.QueueableContext qc) {
System.debug('Account Name is ' + a.Name);
}
}


If you run in Anonymous Apex



Account a = new Account(Name = 'Test');
insert a;

System.enqueueJob(new TestQueueable(a));

a.Name = 'ACME';
update a;


Which Account Name prints in the Queueable, when it executes after the Anonymous Apex transaction completes?



It's important to note that the Queueable (or future, or batch) doesn't start executing until this transaction, the Anonymous Apex we're running, commits successfully and without a rollback. Chronologically, the update DML fires before the Queueable even begins executing.



Here's what we get back:




15:42:44:004 USER_DEBUG [9]|DEBUG|Account Name is Test




One consequence of this feature is that Queueables and Batch Apex cannot have non-serializable member variables. Messaging.SingleEmailMessage, for example, is not serializable. If we'd written



Messaging.SingleEmailMessage a = new Messaging.SingleEmailMessage();
System.enqueueJob(new TestQueueable(a));


we would get back




System.SerializationException: Not Serializable: Messaging.SingleEmailMessage







share|improve this answer


























  • When was the update processed, after the TestQueueable#execute() or prior to it? Trying to understand what would have been the results, if the execute() did not fire immediately.

    – Jayant Das
    Jan 14 at 20:51











  • Prior. The Queueable is not executed until some time after its source transaction commits.(The enqueue operation would have been rolled back if an unhandled exception was thrown).

    – David Reed
    Jan 14 at 20:53








  • 3





    @PranayJaiswal The only case that should happen are platform events. If you have a live example of another case where that happens, log a bug.

    – sfdcfox
    Jan 14 at 21:19






  • 1





    @sfdcfox Isn't the Simon Goodyear use case (at bottom of his blog post) expected? - Data Loader uses AllOrNone = false and hence SFDC will auto-retry the successes in the transaction (batch 0) and hence their futures will fire while the records in the second batch (1) will not be retried.

    – cropredy
    Jan 15 at 0:12








  • 1





    @sfdcfox - hmm I never use data import wizard but would still imagine allornone = false as that is the most practical way to import data.

    – cropredy
    Jan 15 at 4:43



















2














Just to add what David said.



Future / Queueable are just tools that allow us to do another job asynchronously after the main transaction has ended. It's intentionally made dumb so that developers can make it do what they want. There is no SLA for future/queuable calls. They can happen the next second or can happen after 30 mins or even an hour.



Now there can be various use cases like you have to sync data to very transaction oriented external system and you use Queuable. Now even if you delete that record(before queuable has executed), you still want the entity to be sent for audit purpose. Here Queueable gives you that power



If you want the latest data, you can always query it. It suits the need of both Data at the time of main DML happened as well as the time when the actual call is made.






share|improve this answer























    Your Answer








    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "459"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f246580%2fwhen-passing-in-a-collection-of-sobjects-to-a-queueable-what-values-are-used%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    9














    sObjects (and other objects, for that matter) that are instance variables in Queueables and in Batch Apex classes are serialized and stored, and then deserialized at the time the Asynchronous Apex is executed. Field values for sObjects are not refreshed unless your code performs an explicit SOQL query to do so.



    Take this Queueable, for example:



    public class TestQueueable implements Queueable {
    private Account a;

    public TestQueueable(Account a) {
    this.a = a;
    }

    public void execute(System.QueueableContext qc) {
    System.debug('Account Name is ' + a.Name);
    }
    }


    If you run in Anonymous Apex



    Account a = new Account(Name = 'Test');
    insert a;

    System.enqueueJob(new TestQueueable(a));

    a.Name = 'ACME';
    update a;


    Which Account Name prints in the Queueable, when it executes after the Anonymous Apex transaction completes?



    It's important to note that the Queueable (or future, or batch) doesn't start executing until this transaction, the Anonymous Apex we're running, commits successfully and without a rollback. Chronologically, the update DML fires before the Queueable even begins executing.



    Here's what we get back:




    15:42:44:004 USER_DEBUG [9]|DEBUG|Account Name is Test




    One consequence of this feature is that Queueables and Batch Apex cannot have non-serializable member variables. Messaging.SingleEmailMessage, for example, is not serializable. If we'd written



    Messaging.SingleEmailMessage a = new Messaging.SingleEmailMessage();
    System.enqueueJob(new TestQueueable(a));


    we would get back




    System.SerializationException: Not Serializable: Messaging.SingleEmailMessage







    share|improve this answer


























    • When was the update processed, after the TestQueueable#execute() or prior to it? Trying to understand what would have been the results, if the execute() did not fire immediately.

      – Jayant Das
      Jan 14 at 20:51











    • Prior. The Queueable is not executed until some time after its source transaction commits.(The enqueue operation would have been rolled back if an unhandled exception was thrown).

      – David Reed
      Jan 14 at 20:53








    • 3





      @PranayJaiswal The only case that should happen are platform events. If you have a live example of another case where that happens, log a bug.

      – sfdcfox
      Jan 14 at 21:19






    • 1





      @sfdcfox Isn't the Simon Goodyear use case (at bottom of his blog post) expected? - Data Loader uses AllOrNone = false and hence SFDC will auto-retry the successes in the transaction (batch 0) and hence their futures will fire while the records in the second batch (1) will not be retried.

      – cropredy
      Jan 15 at 0:12








    • 1





      @sfdcfox - hmm I never use data import wizard but would still imagine allornone = false as that is the most practical way to import data.

      – cropredy
      Jan 15 at 4:43
















    9














    sObjects (and other objects, for that matter) that are instance variables in Queueables and in Batch Apex classes are serialized and stored, and then deserialized at the time the Asynchronous Apex is executed. Field values for sObjects are not refreshed unless your code performs an explicit SOQL query to do so.



    Take this Queueable, for example:



    public class TestQueueable implements Queueable {
    private Account a;

    public TestQueueable(Account a) {
    this.a = a;
    }

    public void execute(System.QueueableContext qc) {
    System.debug('Account Name is ' + a.Name);
    }
    }


    If you run in Anonymous Apex



    Account a = new Account(Name = 'Test');
    insert a;

    System.enqueueJob(new TestQueueable(a));

    a.Name = 'ACME';
    update a;


    Which Account Name prints in the Queueable, when it executes after the Anonymous Apex transaction completes?



    It's important to note that the Queueable (or future, or batch) doesn't start executing until this transaction, the Anonymous Apex we're running, commits successfully and without a rollback. Chronologically, the update DML fires before the Queueable even begins executing.



    Here's what we get back:




    15:42:44:004 USER_DEBUG [9]|DEBUG|Account Name is Test




    One consequence of this feature is that Queueables and Batch Apex cannot have non-serializable member variables. Messaging.SingleEmailMessage, for example, is not serializable. If we'd written



    Messaging.SingleEmailMessage a = new Messaging.SingleEmailMessage();
    System.enqueueJob(new TestQueueable(a));


    we would get back




    System.SerializationException: Not Serializable: Messaging.SingleEmailMessage







    share|improve this answer


























    • When was the update processed, after the TestQueueable#execute() or prior to it? Trying to understand what would have been the results, if the execute() did not fire immediately.

      – Jayant Das
      Jan 14 at 20:51











    • Prior. The Queueable is not executed until some time after its source transaction commits.(The enqueue operation would have been rolled back if an unhandled exception was thrown).

      – David Reed
      Jan 14 at 20:53








    • 3





      @PranayJaiswal The only case that should happen are platform events. If you have a live example of another case where that happens, log a bug.

      – sfdcfox
      Jan 14 at 21:19






    • 1





      @sfdcfox Isn't the Simon Goodyear use case (at bottom of his blog post) expected? - Data Loader uses AllOrNone = false and hence SFDC will auto-retry the successes in the transaction (batch 0) and hence their futures will fire while the records in the second batch (1) will not be retried.

      – cropredy
      Jan 15 at 0:12








    • 1





      @sfdcfox - hmm I never use data import wizard but would still imagine allornone = false as that is the most practical way to import data.

      – cropredy
      Jan 15 at 4:43














    9












    9








    9







    sObjects (and other objects, for that matter) that are instance variables in Queueables and in Batch Apex classes are serialized and stored, and then deserialized at the time the Asynchronous Apex is executed. Field values for sObjects are not refreshed unless your code performs an explicit SOQL query to do so.



    Take this Queueable, for example:



    public class TestQueueable implements Queueable {
    private Account a;

    public TestQueueable(Account a) {
    this.a = a;
    }

    public void execute(System.QueueableContext qc) {
    System.debug('Account Name is ' + a.Name);
    }
    }


    If you run in Anonymous Apex



    Account a = new Account(Name = 'Test');
    insert a;

    System.enqueueJob(new TestQueueable(a));

    a.Name = 'ACME';
    update a;


    Which Account Name prints in the Queueable, when it executes after the Anonymous Apex transaction completes?



    It's important to note that the Queueable (or future, or batch) doesn't start executing until this transaction, the Anonymous Apex we're running, commits successfully and without a rollback. Chronologically, the update DML fires before the Queueable even begins executing.



    Here's what we get back:




    15:42:44:004 USER_DEBUG [9]|DEBUG|Account Name is Test




    One consequence of this feature is that Queueables and Batch Apex cannot have non-serializable member variables. Messaging.SingleEmailMessage, for example, is not serializable. If we'd written



    Messaging.SingleEmailMessage a = new Messaging.SingleEmailMessage();
    System.enqueueJob(new TestQueueable(a));


    we would get back




    System.SerializationException: Not Serializable: Messaging.SingleEmailMessage







    share|improve this answer















    sObjects (and other objects, for that matter) that are instance variables in Queueables and in Batch Apex classes are serialized and stored, and then deserialized at the time the Asynchronous Apex is executed. Field values for sObjects are not refreshed unless your code performs an explicit SOQL query to do so.



    Take this Queueable, for example:



    public class TestQueueable implements Queueable {
    private Account a;

    public TestQueueable(Account a) {
    this.a = a;
    }

    public void execute(System.QueueableContext qc) {
    System.debug('Account Name is ' + a.Name);
    }
    }


    If you run in Anonymous Apex



    Account a = new Account(Name = 'Test');
    insert a;

    System.enqueueJob(new TestQueueable(a));

    a.Name = 'ACME';
    update a;


    Which Account Name prints in the Queueable, when it executes after the Anonymous Apex transaction completes?



    It's important to note that the Queueable (or future, or batch) doesn't start executing until this transaction, the Anonymous Apex we're running, commits successfully and without a rollback. Chronologically, the update DML fires before the Queueable even begins executing.



    Here's what we get back:




    15:42:44:004 USER_DEBUG [9]|DEBUG|Account Name is Test




    One consequence of this feature is that Queueables and Batch Apex cannot have non-serializable member variables. Messaging.SingleEmailMessage, for example, is not serializable. If we'd written



    Messaging.SingleEmailMessage a = new Messaging.SingleEmailMessage();
    System.enqueueJob(new TestQueueable(a));


    we would get back




    System.SerializationException: Not Serializable: Messaging.SingleEmailMessage








    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 14 at 20:56

























    answered Jan 14 at 20:45









    David ReedDavid Reed

    32k71847




    32k71847













    • When was the update processed, after the TestQueueable#execute() or prior to it? Trying to understand what would have been the results, if the execute() did not fire immediately.

      – Jayant Das
      Jan 14 at 20:51











    • Prior. The Queueable is not executed until some time after its source transaction commits.(The enqueue operation would have been rolled back if an unhandled exception was thrown).

      – David Reed
      Jan 14 at 20:53








    • 3





      @PranayJaiswal The only case that should happen are platform events. If you have a live example of another case where that happens, log a bug.

      – sfdcfox
      Jan 14 at 21:19






    • 1





      @sfdcfox Isn't the Simon Goodyear use case (at bottom of his blog post) expected? - Data Loader uses AllOrNone = false and hence SFDC will auto-retry the successes in the transaction (batch 0) and hence their futures will fire while the records in the second batch (1) will not be retried.

      – cropredy
      Jan 15 at 0:12








    • 1





      @sfdcfox - hmm I never use data import wizard but would still imagine allornone = false as that is the most practical way to import data.

      – cropredy
      Jan 15 at 4:43



















    • When was the update processed, after the TestQueueable#execute() or prior to it? Trying to understand what would have been the results, if the execute() did not fire immediately.

      – Jayant Das
      Jan 14 at 20:51











    • Prior. The Queueable is not executed until some time after its source transaction commits.(The enqueue operation would have been rolled back if an unhandled exception was thrown).

      – David Reed
      Jan 14 at 20:53








    • 3





      @PranayJaiswal The only case that should happen are platform events. If you have a live example of another case where that happens, log a bug.

      – sfdcfox
      Jan 14 at 21:19






    • 1





      @sfdcfox Isn't the Simon Goodyear use case (at bottom of his blog post) expected? - Data Loader uses AllOrNone = false and hence SFDC will auto-retry the successes in the transaction (batch 0) and hence their futures will fire while the records in the second batch (1) will not be retried.

      – cropredy
      Jan 15 at 0:12








    • 1





      @sfdcfox - hmm I never use data import wizard but would still imagine allornone = false as that is the most practical way to import data.

      – cropredy
      Jan 15 at 4:43

















    When was the update processed, after the TestQueueable#execute() or prior to it? Trying to understand what would have been the results, if the execute() did not fire immediately.

    – Jayant Das
    Jan 14 at 20:51





    When was the update processed, after the TestQueueable#execute() or prior to it? Trying to understand what would have been the results, if the execute() did not fire immediately.

    – Jayant Das
    Jan 14 at 20:51













    Prior. The Queueable is not executed until some time after its source transaction commits.(The enqueue operation would have been rolled back if an unhandled exception was thrown).

    – David Reed
    Jan 14 at 20:53







    Prior. The Queueable is not executed until some time after its source transaction commits.(The enqueue operation would have been rolled back if an unhandled exception was thrown).

    – David Reed
    Jan 14 at 20:53






    3




    3





    @PranayJaiswal The only case that should happen are platform events. If you have a live example of another case where that happens, log a bug.

    – sfdcfox
    Jan 14 at 21:19





    @PranayJaiswal The only case that should happen are platform events. If you have a live example of another case where that happens, log a bug.

    – sfdcfox
    Jan 14 at 21:19




    1




    1





    @sfdcfox Isn't the Simon Goodyear use case (at bottom of his blog post) expected? - Data Loader uses AllOrNone = false and hence SFDC will auto-retry the successes in the transaction (batch 0) and hence their futures will fire while the records in the second batch (1) will not be retried.

    – cropredy
    Jan 15 at 0:12







    @sfdcfox Isn't the Simon Goodyear use case (at bottom of his blog post) expected? - Data Loader uses AllOrNone = false and hence SFDC will auto-retry the successes in the transaction (batch 0) and hence their futures will fire while the records in the second batch (1) will not be retried.

    – cropredy
    Jan 15 at 0:12






    1




    1





    @sfdcfox - hmm I never use data import wizard but would still imagine allornone = false as that is the most practical way to import data.

    – cropredy
    Jan 15 at 4:43





    @sfdcfox - hmm I never use data import wizard but would still imagine allornone = false as that is the most practical way to import data.

    – cropredy
    Jan 15 at 4:43













    2














    Just to add what David said.



    Future / Queueable are just tools that allow us to do another job asynchronously after the main transaction has ended. It's intentionally made dumb so that developers can make it do what they want. There is no SLA for future/queuable calls. They can happen the next second or can happen after 30 mins or even an hour.



    Now there can be various use cases like you have to sync data to very transaction oriented external system and you use Queuable. Now even if you delete that record(before queuable has executed), you still want the entity to be sent for audit purpose. Here Queueable gives you that power



    If you want the latest data, you can always query it. It suits the need of both Data at the time of main DML happened as well as the time when the actual call is made.






    share|improve this answer




























      2














      Just to add what David said.



      Future / Queueable are just tools that allow us to do another job asynchronously after the main transaction has ended. It's intentionally made dumb so that developers can make it do what they want. There is no SLA for future/queuable calls. They can happen the next second or can happen after 30 mins or even an hour.



      Now there can be various use cases like you have to sync data to very transaction oriented external system and you use Queuable. Now even if you delete that record(before queuable has executed), you still want the entity to be sent for audit purpose. Here Queueable gives you that power



      If you want the latest data, you can always query it. It suits the need of both Data at the time of main DML happened as well as the time when the actual call is made.






      share|improve this answer


























        2












        2








        2







        Just to add what David said.



        Future / Queueable are just tools that allow us to do another job asynchronously after the main transaction has ended. It's intentionally made dumb so that developers can make it do what they want. There is no SLA for future/queuable calls. They can happen the next second or can happen after 30 mins or even an hour.



        Now there can be various use cases like you have to sync data to very transaction oriented external system and you use Queuable. Now even if you delete that record(before queuable has executed), you still want the entity to be sent for audit purpose. Here Queueable gives you that power



        If you want the latest data, you can always query it. It suits the need of both Data at the time of main DML happened as well as the time when the actual call is made.






        share|improve this answer













        Just to add what David said.



        Future / Queueable are just tools that allow us to do another job asynchronously after the main transaction has ended. It's intentionally made dumb so that developers can make it do what they want. There is no SLA for future/queuable calls. They can happen the next second or can happen after 30 mins or even an hour.



        Now there can be various use cases like you have to sync data to very transaction oriented external system and you use Queuable. Now even if you delete that record(before queuable has executed), you still want the entity to be sent for audit purpose. Here Queueable gives you that power



        If you want the latest data, you can always query it. It suits the need of both Data at the time of main DML happened as well as the time when the actual call is made.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 14 at 21:34









        Pranay JaiswalPranay Jaiswal

        14.6k32553




        14.6k32553






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Salesforce Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f246580%2fwhen-passing-in-a-collection-of-sobjects-to-a-queueable-what-values-are-used%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            1300-talet

            1300-talet

            Display a custom attribute below product name in the front-end Magento 1.9.3.8