Tweet |
Introduction
Winter 22 introduces the capability to roll back pending record changes when a flow element fails at run time. I had two reactions to this - first, that's good; second, how come it didn't always do that? It took me back to the (very few) days when I did Visual Basic work and found out that boolean expressions didn't short circuit - it's something that has been such an integral part of other technologies that I've worked with, it never occurred to me that this would be different.
The original idea for this post was to call out the roll back only applies to the current transaction, and tie in how Apex works as a comparison. But then it occurred to me that in the Salesforce ecosystem there are many people teaching themselves Apex who could probably use a bit more information about how transactions work, So, in the words of Henry James wrote in his obituary for George du Maurier (referring to the novel Trilby):
"the whole phenomenon grew and grew till it became, at any rate for this particular victim, a fountain of gloom and a portent of woe"
Transactions
A transaction is a collection of actions that are applied as a single unit. Transactions ensure the integrity of the database in the face of exceptions, errors, crashes and power failures. The characteristics of a transaction are known by the acronym ACID:
- Atomic - the work succeeds entirely or fails entirely. Regardless of what happens in terms of failure, the database cannot be partially updated.
- Consistent - when a transaction has completed, the database is in a valid state in terms of all rules and constraints. This doesn't guarantee the data is correct, just that it is legal from the database perspective.
- Isolated - the changes made during a transaction are not visible to other users/requests until the transaction completes.
- Durable - once a transaction completes, the changes made are permanent.
Transactions in Apex
Catching Exceptions
1 2 3 4 5 6 7 8 9 10 11 12 13 | Account acc= new Account(Name= 'TX Test' ); Contact cont= new Contact(FirstName= 'Keir' , LastName= 'Bowden' ); String result= 'SUCCESS' ; try { insert acc; cont.AccountId=acc.Id; insert cont; } catch (Exception e) { result= 'Error ' + e.getMessage(); } return result; |
Taking Back Control
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | SavePoint preAccountSavePoint=Database.setSavePoint(); Account acc= new Account(Name= 'TX Test' ); Contact cont= new Contact(FirstName= 'Keir' , LastName= 'Bowden' ); String result= 'SUCCESS' ; try { insert acc; cont.AccountId=acc.Id; insert cont; } catch (Exception e) { result= 'Error ' + e.getMessage(); Database.rollback(preAccountSavePoint); } return result; |
Rolling Back Flow Transactions
After that lengthy diversion into Apex, hopefully you'll understand why I expect everything to rollback the transaction automatically when there is an error - it's been a long time since it has been my problem. Per the Winter 22 release notes, flow doesn't do this :
Previously, when a transaction ended, its pending record changes were saved to the database even if a flow element failed in the transaction
and bear in mind that is still the case - what has been added is a new Roll Back Records element you can use in a fault path. Why wasn't this changed to automatically roll back on error? For the same reason that Visual Basic didn't start short circuiting boolean expressions - there's a ton of existing solutions out there and some of them will rely on flow working this way. While it's not ideal, nor is introducing a breaking change to existing customer automation.
Something else to bear in mind is that this rolls back the current transaction, not necessarily all of the work that has taken place in the flow. Per the Flows in Transactions Salesforce Help article, a flow transaction ends when a Screen, Local Action or Pause element is executed. Continuing with my Account and Contact approach, if you've inserted the Account and then use a Screen element to ask the user for the Contact name, the Account is committed to the database and will persist regardless of what happens to your attempt to create a Contact. Much like the batch Apex note above, rolling back the second (Contact) transaction has no effect on the first (Account) transaction as that has already completed successfully.
Enjoying Transactions?
And then scale them up across many microservices.
Many years ago I used to have to manage transactions myself, and in one particular case I had to work on distributing transactions across a number of disparate systems. It was interesting and challenging work, but I don't miss it!
No comments:
Post a Comment