If a Microflow does not finish, do all commits get rolled back?
We have a Microflow that backs-up our documents to OneDrive. We grab 100 at a time, call the OneDrive API for all 100 then update an IsSynced property on the Document and then use a Commit activity and then use an exclusive split to see if we need to continue or not. This process eats up too much memory and makes our app unusable so I have only been running it after work hours. I usually have to kill it by restarting the Application in the morning. What I have found is that even though we set the IsSynced property and do a commit action that the save is not actually happening in the database. When I go to kick it off again it runs for the same Documents. And I can also use oData and load the data into Excel and see that even though it committed the IsSynced property is still false. It does work in Development and in Acceptance so I know the Microflow works. What appears to be happening is that because the Microflow gets killed by me restarting the Application that any commits were rolled back as if everything in the Microflow is in a single transaction. Does anyone have any insight as to what is happening and how to fix it?
Everything that happens in one request to the mendix runtime server is part of the same database transaction. If anything fails, either in the main microflow, or one of the submicroflows, all database changes are rolledback.
This is usually what you want: suppose you have some complex multi-microflow logic sitting behind a save button in your webpage, this should either completely fail, or completely succeed.
For long running microflow this may not be the best solution. There are a few ways you can influence the transaction scope:
Have a recurrent scheduled microflow which only does a small part of the work every few minutes. If it fails, the next time it runs, it can pick up all the remaining work. Everything done in the failed scheduled microflow and its submicroflows will be rolled-back.
Use the transaction control actions from the AppStore, as mentioned by Larn: EndTransaction and StartTransaction.
Use a custom java action to run a submicroflow in a separate context. See Core.execute. If you create a new context for every exection, it will be run in a separate transaction.
And the option i usually prefer, as it also loadbalances your submicroflows across your runtime instances:
Run the submicroflow by calling it from a new http request: create a REST or WebService API for it and call it from the outer microflow.
That is indeed true. A microflow ends the database transactions when it finishes.
If you want you can use the EndTransaction and StartTransaction java actions to actually commit the objects before the microflow ends. This can be found in the community commons module.
There are also some advanced and expert learnings specifically about this topic if you’re interested in them.