In ADF transactions are defined and owned by the underlying business service implementation used
within the Model layer of the
application. As example ADF Business Components take out connections and
transactions with the database. Such services are then exposed to the View
Controller layer through an abstraction known as a Data Control for the View Controller to work with.
As our application can utilize
multiple data controls, the ADF Controller (ADFc) through the facilities
provided by the task flow transaction and data control scope options, allow one
or more data controls to be grouped together and committed or rolled back as a group.
The underlying business services
still own the transaction and ultimately execute the commit and rollback operations,
but the ADF Controller defines the
boundaries of the task flow transaction, namely where the transaction
starts and stops and which data controls are involved.
For the bounded task flow
transaction option itself there are only 4 options:
·
"<No Controller Transaction>"
·
"Always Begin New Transaction"
·
"Always Use Existing Transaction"
·
"Use Existing Transaction if Possible"
Data control scope:
·
Isolated
·
Shared (Default)
Shared Scope
When a task flow defines a shared data control scope, this implies
the task flow will attempt to share any
instance of a data control (and by implication it's state) with the task
flow's caller if the data controls have the same definition, rather than
creating a new instance.
Isolated Scope
If a task flow defines an isolated data control scope, even if
both task flows use the same design time data control definition, at runtime each
task flow will have their own instance of
the data control.
Data Control Frame
The Data Control Frame is the
magic behind how this works. Essentially each task flow has the potential to
have its own data control frame containing a list of the used data controls. A
data control frame is created at runtime
for your application's unbounded task flow and any isolated data control scoped
bounded task flow.
However when a bounded task flow
specifies a shared data control
scope the current task flow uses the
data control frame of the caller
rather than creating its own, giving the called task flow the chance to share
data control instances attached to the frame.
Alternatively if the bounded task flow
specifies an isolated data control
scope, a new frame will be created and a
new instance of any data controls used by the bounded task flow will be
attached to this new frame.
Now let’s see the different
options available in transaction management in Taskflows:
Always Begin New Transaction
It is used to start a new transaction in your
application. Typically this option is coupled with the isolated data control scope and a new separate data control frame.
If a bounded task flow does start
with a new transaction, when it wishes to
complete it must call a task flow return activity commit or rollback. These
call the underlying commit() or rollback() operations on the associated data
control frame, essentially committing or rolling back all data controls
attached to the frame.
Always Use Existing Transaction
A bounded task flow that uses the
"Always Use Existing Transaction" option is designed to share the transaction of the previous task
flow in your application; it will not start a new transaction.
On closing it cannot make use of a commit or rollback task flow return
activity, at design time such a task flow return activity will be flagged in
error. Only a task flow that starts a new transaction can call these. In this
case the "Always Use Existing Transaction" option will depend on its
caller to finalize the transaction. Instead the "Always Use Existing
Transaction" task flow simply calls a task flow return activity with its
End Transaction property set to "<Default> none".
Use Existing Transaction If
possible
It is the most flexible of the transaction options and it is a combination of
the "Always Begin New Transaction" and "Always Use Existing
Transaction" options.
If "Use Existing Transaction
if Possible" is used with an
isolated data control scope, it operates in the same manner as the "Always
Begin New Transaction" with an isolated data control scope creating a
new data control frame.
If "Use Existing Transaction
if Possible" is used with a shared
data control scope its behaviour is dependent
on if a transaction is open on the shared
data control frame of the caller.
If a transaction is open it has the same behaviour of
"Always Use Existing Transaction" with a shared data control scope.
If a transaction is not open, it behaves the same as
"Always Begin New Transaction" and a shared data controls scope.
No Controller Transaction
"<No Controller
Transaction>" option is restricted in its interaction with the data
control frame; it does have a more liberal relationship with its relating data
controls and their transactions.
·
Doesn't start a transaction on the data control frame like
the "Always Begin New Transaction" option
·
Doesn't check or enforce if a
transaction is
open on the data control frame
·
Will not call finalize the data
control frame transaction by calling the
Data Control Frame commit() or rollback().
The established rules still apply for the data control scope
though. If an isolated data control scope is specified for the task flow a new
data control frame and data controls will be instantiated. For a shared data
control scope the previous task flow's data control frame and data controls
will be shared.