Workflow Services and the DTC

by mgordon 7. February 2008 04:56

As noted in a former post, I implemented a change order system using Windows Workflow.  Recently, the system was deployed for User Acceptance Testing and odd things began to happen.  The system is using both tracking and persistence services and what we observed in the Sql Profiler was that the Sql to insert the persistence record was never making it to the database, but the tracking was working fine.

I implemented a handler for the ServicesExceptionNotHandled event on the WorkflowRuntime object, but nothing was being raised.  After a couple of hours poking and prodding, I finally linked the problem to the windows firewall.  If the firewall was turned off, everything worked as expected.  I spent some time researching the problem and found a couple of posts on the Microsoft Forums here and here that discuss the SharedConnectionWorkflowTransactionService.  Apparently, when the persistence and tracking data are in two different databases, the DTC gets involved any updates to the data and the firewall was blocking the DTC traffic. 

As mentioned in one of these posts, I combined the persistence and tracking databases into one, and added the SharedConnectionWorkflowTransactionService to runtime when I started up.  The combination of these actions removed the dependency on the DTC and all is working fine, now. 

Tags: , ,

.Net | Sql Server 2005 | Workflow

WF First Impressions

by mgordon 29. November 2007 05:25

I've been working with a team since March on a huge, complicated billing and customer management system for a utility company.  Part of what the application does is manage change orders of various types.  Depending on the order's type, it is routed to various locations so that actions can be performed at each of them.  When this requirement was originally discussed, it was thought that it would be sufficient to define the paths the orders would go on, statically.  That is, the order of stops would always be the same.  These paths were allowed to branch, but there was no decision logic involved in them.  I looked at WF, at that time, and decided it would be overkill.  I then went about writing an engine to manage the process of promoting the orders through the paths which was a huge, messy task.

A few months later, it as decided that decision logic was, in fact, going to be needed in the flows.  I reasoned that I had two options at this point.  I could either go back into the engine code I had written and implement some polymorphic way to call business logic (such as coding the calls against an Interface and loading up a configured class that implemented the interface at runtime)...OR I could toss the engine and look at workflow, again.  I chose to do the latter.  I hadn't yet used workflow on any production application, so I armed myself with a couple of books (this one and this one) and dug in.

Now that this portion of the application is rewritten, I wanted to post about my take on the experience. 

Less Time and Code
First of all, I was extremely impressed at how much code I DIDN'T have to write for this implementation.  In writing my engine, I had to write a ton of code to determine whether or not the order was on a path parallel to the one I was currently processing and whether I could continue or not.  Having Workflow handle all that for me was a huge bonus. This also translated into a great deal of time savings.  I implemented several complicated flows and had a working system in about two and a half weeks with the previous engine I wrote taking a couple of months.

Expressing Complicated Logic in a Visual Way
I'm not sure why, but I kept thinking I was going to encounter a set of logic I needed to implement that I could not express with the supplied workflow activities, but I did not.  I didn't need to write any custom activities (although that would have been a good exercise to have had) in order to get the job done.  I found the activities that came in the box to serve me very well.

Along with the good, though, I did encounter a few things that I wasn't crazy about.

Inheritance and the Designer
As I worked through the various flows I had to implement, I kept encountering bits of code tied to code activities that they all the flows had in common.  Naturally, my instinct told me to refactor these, put them into one place, and share them.  So, I pulled all the common bits into a base class and inserted it into the inheritance hierarchy.  I created the base class and had it inherit from SequentialWorkflowActivity (the base class, by default, of a sequential workflow) and then modified my flows to inhert from this base class.  What I expected, was for the designer to recognize the inherited methods and allow me to tie my code activities to them.  However, the designer did not display any of these methods for me to choose from, and when I manually entered the method name it both insisted upon adding the method to the workflow again AND complained that it could not do so since the class it was inheriting from already had a method by that name.  I should mention that I was using VS 2005 for my development and have not tried to do a similar thing in VS 2008.  This may have been corrected.  Also, there may very well be a way to accomplish what I needed, but the way that seemed obvious to me did not work as I expected it to.

Communication Between Workflow and Host
All communication between the workflow runtime (within which your workflow executes) and the host of the runtime is asynchronous.  To communicate into the workflow, you need to fire an event into it and the workflow needs to be in a state of actively listening for that particular event.  For the workflow to communicate with it's host, an event is fired from within the flow and the host needs to have a handler for the event.  For some of my flows, it was necessary for the flow to occasionally ask the user how to proceed with a messagebox allowing a yes or no answer.  The amount of code to implement this was quite a bit more than I expected.  I understand that the workflow engine is running on a different thread and that all this communication needs to be synchronized, but I have to think that the API providing this functionality will be improved over time to make quicker work of implementing this type of communication.

You can expect that I'll be posting more details about workflow and my experiences with it along the way.  I'm reluctant to share too much at this point since I still consider myself to be a rank amateur with the technology in regard to best practices.

Tags:

Workflow

Powered by BlogEngine.NET 1.5.0.7
Theme by Extensive SEO