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
    10 hours ago
















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
    10 hours ago














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 10 hours ago









Adrian Larson

106k19112238




106k19112238










asked 10 hours ago









user11235813user11235813

4,491547127




4,491547127








  • 1





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

    – Adrian Larson
    10 hours ago














  • 1





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

    – Adrian Larson
    10 hours ago








1




1





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

– Adrian Larson
10 hours ago





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

– Adrian Larson
10 hours ago










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
    10 hours ago











  • 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
    10 hours ago













  • Great to know this. I had always thought that any batch (or scheduled) process always works on the latest record set, even if not explicitly retrieved.

    – Jayant Das
    10 hours ago






  • 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
    9 hours ago






  • 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
    6 hours ago





















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
      10 hours ago











    • 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
      10 hours ago













    • Great to know this. I had always thought that any batch (or scheduled) process always works on the latest record set, even if not explicitly retrieved.

      – Jayant Das
      10 hours ago






    • 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
      9 hours ago






    • 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
      6 hours ago


















    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
      10 hours ago











    • 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
      10 hours ago













    • Great to know this. I had always thought that any batch (or scheduled) process always works on the latest record set, even if not explicitly retrieved.

      – Jayant Das
      10 hours ago






    • 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
      9 hours ago






    • 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
      6 hours ago
















    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 10 hours ago

























    answered 10 hours ago









    David ReedDavid Reed

    31.6k61746




    31.6k61746













    • 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
      10 hours ago











    • 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
      10 hours ago













    • Great to know this. I had always thought that any batch (or scheduled) process always works on the latest record set, even if not explicitly retrieved.

      – Jayant Das
      10 hours ago






    • 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
      9 hours ago






    • 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
      6 hours ago





















    • 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
      10 hours ago











    • 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
      10 hours ago













    • Great to know this. I had always thought that any batch (or scheduled) process always works on the latest record set, even if not explicitly retrieved.

      – Jayant Das
      10 hours ago






    • 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
      9 hours ago






    • 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
      6 hours ago



















    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
    10 hours ago





    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
    10 hours ago













    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
    10 hours ago







    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
    10 hours ago















    Great to know this. I had always thought that any batch (or scheduled) process always works on the latest record set, even if not explicitly retrieved.

    – Jayant Das
    10 hours ago





    Great to know this. I had always thought that any batch (or scheduled) process always works on the latest record set, even if not explicitly retrieved.

    – Jayant Das
    10 hours ago




    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
    9 hours ago





    @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
    9 hours ago




    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
    6 hours ago







    @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
    6 hours ago















    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 9 hours ago









        Pranay JaiswalPranay Jaiswal

        14.3k32552




        14.3k32552






























            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

            GameSpot

            日野市

            Tu-95轟炸機