function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
KJesseKJesse 

Reverting Objects after Http Callout

Hi I am sending objects to an external database via httpcallout in triggers. Rarely database operations could fail and if they do I would like to revoke the operation that occured in salesforce; ie if the delete fails I would like to either do a savepoint or clone the object prior to the delete and add it back. Similar for an update I would like to revert the object to its previous fields. 

This is difficult with an asyncronous @future call. I can't think of any solutions. I am returning to salesforce the http error so I know what has happened but I am not sure how to properly revert seeing I cannot do savepoints in a @future call.
Best Answer chosen by KJesse
Daniel BallingerDaniel Ballinger
I don't think there will be an easy answer to that problem. The point of enforcing the callouts in the async future methods is to allow the Salesforce database transactions to finish faster, as they don't need to wait for the callout to occur.

By the time your async future methods actually runs the orginating transaction has long been committed to the database. You would need to maintain the complete state of the object to be reverted independantly so that you would know which fields to reset.

For something like an update operation you could keep a JSON representation of the initial state. However, by the time your callout fails and you go to revert the object, what's to have prevented another update to the same object from occuring.

I.e.
  1. User A changes the Account.Name to "Foo".
  2. Before the future callout can occur, User B changes the Account.Name to "Bar"
  3. The future Callout from User A fails, and attempts to revert the Account Name field to? Should it be "Foo", should it detect the subsequent update by User B?
  4. The future Callout from User B occurs, what values should it send to the web service?
Personally, I think trying to revert the changes in Salesforce is going to get complicated. Maybe look at maintiaining a list of records to sync with the external system and track any problems there.

All Answers

Daniel BallingerDaniel Ballinger
I don't think there will be an easy answer to that problem. The point of enforcing the callouts in the async future methods is to allow the Salesforce database transactions to finish faster, as they don't need to wait for the callout to occur.

By the time your async future methods actually runs the orginating transaction has long been committed to the database. You would need to maintain the complete state of the object to be reverted independantly so that you would know which fields to reset.

For something like an update operation you could keep a JSON representation of the initial state. However, by the time your callout fails and you go to revert the object, what's to have prevented another update to the same object from occuring.

I.e.
  1. User A changes the Account.Name to "Foo".
  2. Before the future callout can occur, User B changes the Account.Name to "Bar"
  3. The future Callout from User A fails, and attempts to revert the Account Name field to? Should it be "Foo", should it detect the subsequent update by User B?
  4. The future Callout from User B occurs, what values should it send to the web service?
Personally, I think trying to revert the changes in Salesforce is going to get complicated. Maybe look at maintiaining a list of records to sync with the external system and track any problems there.
This was selected as the best answer
KJesseKJesse
Thanks Daniel! I think I will just track the database discrepancies.