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♦
Jan 14 at 20:15
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 Jan 14 at 20:15
Adrian Larson♦
106k19113241
106k19113241
asked Jan 14 at 20:13
user11235813user11235813
4,505547128
4,505547128
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
add a comment |
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
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
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 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
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
|
show 10 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
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 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
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
|
show 10 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
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 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
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
|
show 10 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 Jan 14 at 20:56
answered Jan 14 at 20:45
David ReedDavid Reed
32.6k71950
32.6k71950
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
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 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
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
|
show 10 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
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 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
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
|
show 10 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 Jan 14 at 21:34
Pranay JaiswalPranay Jaiswal
14.8k32553
14.8k32553
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♦
Jan 14 at 20:15