When passing in a collection of sObjects to a Queueable what values are used?
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
add a comment |
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
1
Please try to include obvious tags. When a question relates to[apex]
, it should be tagged as such.
– Adrian Larson♦
10 hours ago
add a comment |
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
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
apex queueable-interface
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
add a comment |
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
add a comment |
2 Answers
2
active
oldest
votes
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
When was theupdate
processed, after theTestQueueable#execute()
or prior to it? Trying to understand what would have been the results, if theexecute()
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 usesAllOrNone = 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
|
show 8 more comments
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.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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
When was theupdate
processed, after theTestQueueable#execute()
or prior to it? Trying to understand what would have been the results, if theexecute()
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 usesAllOrNone = 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
|
show 8 more comments
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
When was theupdate
processed, after theTestQueueable#execute()
or prior to it? Trying to understand what would have been the results, if theexecute()
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 usesAllOrNone = 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
|
show 8 more comments
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
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
edited 10 hours ago
answered 10 hours ago
David ReedDavid Reed
31.6k61746
31.6k61746
When was theupdate
processed, after theTestQueueable#execute()
or prior to it? Trying to understand what would have been the results, if theexecute()
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 usesAllOrNone = 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
|
show 8 more comments
When was theupdate
processed, after theTestQueueable#execute()
or prior to it? Trying to understand what would have been the results, if theexecute()
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 usesAllOrNone = 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
|
show 8 more comments
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.
add a comment |
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.
add a comment |
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.
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.
answered 9 hours ago
Pranay JaiswalPranay Jaiswal
14.3k32552
14.3k32552
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
1
Please try to include obvious tags. When a question relates to
[apex]
, it should be tagged as such.– Adrian Larson♦
10 hours ago