batching : IPendingWork.Commit

MSDN Says :

"

The workflow runtime engine calls the Commit method when its semantics dictate that the pending work in the work batch should be committed. When it reaches a commit point, the workflow runtime engine calls the Commit method on each IPendingWork object in its work batch; the workflow runtime engine passes the Commit method the collection of items associated with that IPendingWork object. Either all of the work in a batch succeeds or none of it succeeds. You should throw an exception if any of the work items passed to the Commit method in your implementation cannot be committed. Depending on your implementation, you may want to perform some rollback in your Commit method if it cannot commit its work items. If the workflow runtime engine successfully commits all of the work in the work batch, it calls Complete with the succeeded parameter set to true; otherwise, it calls Complete with succeeded set to false.

"

1. Please could somebody explain just when the Commit will be called. How does the runtime determine when to call commit MSDN says, "when its semantics dictate". What does this mean Under what conditions will the Commit be called

2. Say we have a TransactionScopeActivity with various CallExternalMethodActivity objects calling a local service. The local service methods thus called will use WorkBatch.Add(this, item) for each call. The Commit method will be called by the runtime "when its semantics dictate" -

I suppose it will be called after the TransactionScope has completed
Why do we have to use batching, in addition to the TransactionScope Why can the TransactionScope not handle the transaction by itself
In sum, what is the relationship between the TransactionScope and Batching

3. Is Batching another way to handle transactions, or is it more than that






Answer this question

batching : IPendingWork.Commit

  • Cang Sam

    Thank you everybody. I think we've reached... somewhere!

    I remember reading that Batching was also about keeping the integrity of the workflowInstance / Persistence image i.e. keeping them in synch.

    But that's another story...

    Kind Regards
    Jean-Pierre



  • oulisee

    I think we are getting to where my trouble lies with batching.

    If I don't know for sure when the Commit is going to happen, how do I know when my activities are going to execute It seems that the transactional-activities-with-batching will be executed non-deterministically, the indeterminate factor being when Commit is going to be called.

    We say "when the runtime figures out that a Commit is necessary". Does anybody know when is this is



  • orent

    Maurice,

    you're maybe right, but for me a TransactionScopeActivity is not just for doing ACID transactions on sql data, but also for confirming a workflow episode (by persisting it, without unloading it) ;and this  could also be the reason why we MUST  use a persistence service when we use a TransactionScopeActivity.

    According to Moustafa (MS):  http://msdn2.microsoft.com/en-us/library/aa663362.aspx

    <<

    If a WorkflowPersistenceService is present (that is, added to the WorkflowRuntime instance) the workflow runtime engine uses this service to persist workflow instance state to a storage medium. This might occur at the following points:

    On the completion of activities that are marked with the PersistOnCloseAttribute (for example, transaction scope activities)
    Before workflow instance completion
    Before workflow instance termination
    When the workflow goes idle
    When WorkflowInstance.Unload or WorkflowInstance.TryUnload are called
    >>

    Serge



  • JFoushee

    Hello Jean Pierre,

    To answer your question 1 : Commit will be called during the next persistence point (e.g when transactionScope activity commits).

    To answer your questions 2 & 3 :

    TransactionScope Activity is a way to handle ACID transactions; when a transactionScopeActivity correctly completes, the transaction is committed AND a persistence point is set up.

    If your application crashes,you can restart the workflow application  and the workflow will resume just AFTER the persistence point (that's why we have to use a persistence service when we use TransactionScope activities).

    Now,  if you have non ACID actions (in activities) (e.g display something to the screen,)  before your transactionscope Activity and if you want these Non ACID activities to execute exactly once ,  you can delay their execution to  the next persistence point . IPending work is a great way to achieve this.

     

    Hope this helps

    Serge



  • Martin Mason

    Well keeping the workflow and data in synch is what batching is all about. Like I wrote in my previous post, if the workflow runtime crashes after it committed a TransactionScopeActivity and it is restarted later the whole TransactionScopeActivity will be executed again. Now that may be a problem it may not, that depends on your situation.

    But with batching the actual transactional work isn't done until the workflow is persisted, and in the same transaction. So if there is a crash the state of the data and the state of the workflow will be saved the same way and can be restarted safely.

    Maurice

  • Steve Severance

    Hi,

    You are right both Batching and TransactionScopeActivity can be used to do transactional work in a workflow. The difference is that the TransactionScopeActivity commits all work as soon as the TransactionScopeActivity is finished while Batching saves all items to commit and only commits them when the workflow runtime determines there is a commit point. Batching also uses a TransactionScope so both are transactional.

    So what is the difference. Suppose your workflow doest some stuff, is unloaded into the persitence store, coninues executing, starts an TransactionScopeActivity, doest some work, terminates the TransactionScopeActivity and then before the workflow is finished or persisted again has the runtime crash on it.

    Now the transaction has completed and is commited but the state of the workflow is still as it was last persisted, ie before the TransactionScopeActivity was ecexuted. Suppose the runtime is restarted, it will detect and reload the workflow and continue from the unloaded point so do the TransactionScopeActivity again.

    Now if you use Batching to commit the data things work a little different. The WorkBatch is commited in a TransactionScope but this will include the WorkflowPersistenceService itself. So if the worflow runtime crashes before the batch is commited no work is saved at all and everything can safely be repeated. If on the otherhand the batch is saved and the workflow runtime crashes after that the workflow will be restarted from the second time it was saved and not repeat the work done.

    So when does the workflow runtime decide there is a commit point.
    I don't know exactly but at the very least when a workflow terminates or is unloaded. There might be more point though.

    Maurice

  • Jagjot Singh

    Serge,

    As far as I know there is no implicit persistence point at the end of a TransactionScopeActivity. So if the workflow was persisted before the TransactionScopeActivity and crashes right after it the restart point would be before the TransactionScopeActivity. But I haven't tested this either so might have missed something.

    Maurce


  • Carsten Kanstrup

    1.no.

    2.if you have a crash, and you restart your workflow, the workflow will run from the last persistence point (in this case persistence point triggered by a transaction).

    overhead well, the job has to be done, anyway...

    3.no, I've just tested it without persistence; but I don't see a lot of benefits of batching without persistence.

    Serge



  • vicarious

    I just took a look with Reflector and its basically as Serge says.

    Every time the WorkFlow.Persist() is called the WorkBatch is committed. This happens when the workflow goes idle AND the UnloadOnIdle is set, the workflow is explicitly unloaded, the runtime is unloaded or when the workflow terminates.

  • mobigital

    Jean-Pierre,

    As far as I understand it , this probably means : "when there is a persistence point" ;

    Here are 2 examples :

    example1.

    <Activity1> uses a IPendingWork service

    <TransactionScopeActivity1>

    <Activity2>

    <Activity3>

    </TransactionScopeActivity1> -->transaction completes successfully here->persistence point->Commit of the IPendingWorkServiceswill be called

    <Activity 3>

    example2. Persistence Service has been added and UnLoadOnIdle is true

    <Activity1> uses a IPendingWork service

    <Activity2>

    <Delay Activity>->Unload->Persistence point->Commit of the IPendingWorkkService

    <Activity3>



  • JavaBoy

    Hi Serge,

    Thank you for responding.

    So, in a TransactionScope, the items are commited when the TransactionScope completes.

    1. Is batching required when using TransactionScope
    2. Why is persistence required when using TransactionScope I suppose this will add some overhead to our applications i.e. compulsory persistence upon TransactionScope completion
    3. Is persistence required when using batching What is the relationship between batching and persistence

    Jean-Pierre








  • ruippeixotog

    It might be worth mentioning that batching can still be done inside a TransactionScopeActivity, and that's where it makes more sense, up to a point, to me.

    The thing with batching outside of a transaction scope is that it does change the semantics of the activity in a way that might, or might not be, expected by the developer using it. For example, it seems natural to assume that, outside of a transaction, the effects of executing a given activity will be immediately visible, but if the activity batches its work, then that might not necessarily happen, which can cause trouble sometimes. (Notice the same thing will be true if you mix batching and non-batching activities in a transaction scope, btw).


  • fruce

    Maurice,

    WF program instances resume their execution from their last persistence point, so if your app crashes after committing a TransactionScopeActivity(->persistence point) it will resume from the last persistence point : my understanding is in this case the TransactionScopeActivity won't be executed again. (I haven't tested it, however...).

    Serge



  • Grant Jenkins

    I agree there is the possibility for confusion when what gets committed but fail to see why adding a TransactionScopeActivity would help. After all the developer would expect the change to be committed and visible as soon as the TransactionScopeActivity is finished and when batching is used this is most likely not the case. In fact a TransactionScopeActivity would be used with nothing transactional happening in the transaction. Unless of course adding something to the WorkBatch is transactional but I was under the impression that it is not.

    But then again maybe I am missing something

    Maurice

  • batching : IPendingWork.Commit