I have a flow service that has many sequences (and it has child sequences too), so does that mean I can only put startTransaction outside of any SEQUENCE ?
For example, my flow service is like this:
... (do something here)
SEQUENCE (TRY & CATCH -> this is the top-most SEQUENCE)
SEQUENCE (TRY)
... (do another things here)
Invoke: [B]startTransaction[/b]
SEQUENCE (TRY & CATCH)
SEQUENCE (TRY)
Invoke: insertToDB_adapter_service
Invoke: [B]commitTransaction[/b]
SEQUENCE (CATCH)
Invoke: [B]rollbackTransaction[/b]
EXIT flow & signal FAILURE
... (do another things here)
SEQUENCE (CATCH)
... (do another things here)
Is it okay to put startTransaction inside the top-most SEQUENCE ?
My second question: is it true that after invoking rollbackTransaction, we must always call: EXIT flow & signal FAILURE ? (as depicted in above example)
This is fine. As you have your db operations being executed inside your “inner try/catch”, it is okay if you have startTransaction as first before your inner Try/Catch. Remember, you can have nested transactions as well.
It is not required to have Exit Flow with failure all the time. It is based on what you want to do when there is an exception in your try block. Generally, if you dont exit with failure from your catch block, the flow service execution state will be displayed as success and you will not be able to identify which execution is real success and which one has got failed.
Be careful about overusing try/catch sequences. Generally, only top-level services should have them.
For calls to adapter services I usually follow these guidelines:
Create a FLOW service that calls the adapter service(s). Add the try/catch sequences to the FLOW service.
Do nothing else in that service other than call the adapter service(s).
If you must have the adapter service calls within a larger service, do nothing else within the start/end transaction calls if at all possible. E.g. don’t map, call other services, etc. Keep the scope of the transaction as small as possible.
Design the integration to avoid XA transactions if at all possible.
Avoid using implicit transactions if at all possible.
Let’s say the above flow service name is InsertDataTx. So the main flow service become:
... (do something here)
SEQUENCE (TRY & CATCH -> this is the top-most SEQUENCE)
SEQUENCE (TRY)
... (do another things here)
Invoke: [B]InsertDataTx[/b]
... (do another things here)
SEQUENCE (CATCH)
... (do another things here)
Did you mean like that?
Just a little note for other people who haven’t know:
The Try-Catch Sequence is configured like this:
SEQUENCE (TRY & CATCH) -> Exit when [B]Success[/b]
SEQUENCE (TRY) -> Exit when [B]Failure[/b]
...
SEQUENCE (CATCH) -> Exit when [B]Done
[/b] ...
Can inhibit reusing the service in a new context–e.g. a new caller wants to do it’s own handling of errors
Generally, try/catch in FLOW is intended to notify someone that something went wrong, rather than trying to recover in some way. That’s usually better left to the top level. This mirrors the general exception handling rule of thumb–don’t catch things that you can’t do anything about.
As with any coding guideline, it’s up to the developer to do what makes sense for a given situation.