21

Question

If I invoke an @future method from a trigger that is performing a calculation based on data that is being committed in the trigger am I at a risk for a race condition?

Background

We're implementing a complex rollup calculation that we'd like to be real time (or near real-time). Specifically we're rolling up the latest activity date for tasks across and account hierarchy segmenting by the type of account. We can't use the standard LastActivityDate field since we need to exclude some auto-generated tasks. To calculate this date is a pretty intensive query so we don't want to hold up the task commit while the calculation takes place. However, if the rollup calculation occurs before the trigger fully commits the data will be incorrect. Is this a realistic concern?

17

@Future's are queued transactionally along with other db changes in the trigger transaction, so the future can't be executed until the enqueuing transaction commits. (and conversely, if the trigger transaction never commits due to errors etc, the @future is never executed)

  • hallelujah, that's so good to know – Ralph Callaway Mar 20 '13 at 2:25
  • 1
    This answer is misleading. It is factually correct, but neglects to consider the effects of other transactions in the database, which may execute before the execution of the future method. In the user's case, this may not be important, as they are concerned with "latest date", and it seems that "eventually consistent" meets their case close enough. However, for different use cases, the addition or deletion of rows in the database may cause the future method to operate on a totally different set of data than expected. @Ralph – Pittsburgh DBA Jan 27 '15 at 20:29
  • 1
    @PittsburghDBA care to provide an example of where this effects would cause an issue? Seems like it would be as simple as the answer suggests – Ralph Callaway Jan 28 '15 at 22:40
5

The safe bet would be to take whatever @superfell's puts forward as being a more authoritative answer.

That said, I did come across the another question that showed signs of being a trigger race condition in the askers described symptoms. Future Method is not updating value of a field

This may not be how it actually works, but the user fired 3 separate future methods one after the other in the same transaction. Each future method did the same thing. Retrieve a single record, increment a counter, update the record with the new value. When run in parallel this would be a text book race condition.

I had a look in the Asynchronous Processing in Force.com doc to see if I could find any clues about how the future methods ran.

This diagram from page 3 showed the future method requests being passed out to various worker threads on different Application Servers in parallel.

Asynchronous Queue

The diagram may be an oversimplification, but it certainly looks like the future jobs could run in parallel in different threads.

  • Excellent point, fortunately we're only doing one @future call so we should be good as long as it doesn't execute until after the trigger transaction completes – Ralph Callaway Mar 20 '13 at 2:28
  • @Ralph. Yes, I agree that superfell's answer seems correct for your specific case with the transaction rollback. I'm still not so sure about the more generic issue of future method race conditions. – Daniel Ballinger Mar 20 '13 at 2:31
  • Seems like they would definitely be at risk since multiple workers could be processing your queued @future calls at the same time, voted it up, it's good for the next guy to have that in here – Ralph Callaway Mar 20 '13 at 2:36
  • 1
    Certainly they can run in parallel, and if they are trying to update the same data, you need to get the locking right to not loose updates. – superfell Mar 20 '13 at 2:44
  • 1
    FOR UPDATE is all there is. – superfell Mar 20 '13 at 2:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.