Thursday, October 29, 2009
BizTalk Orchestration Designer Crashes Visual Studio
Tuesday, October 20, 2009
Use of interfaces within BizTalk Orchestrations and XLANG/s
orchestrationHelper = Andrew.InterfacesXLANGs.Components.OrchestrationHelperFactory.CreateHelper(helperSpecification);
And in the next expression shape I call the business logic:
orchestrationHelper.DoStuff();
Again, this is almost as simple an orchestration as it is possible to get. However, when I try to compile it I get the following error:
Error 1 a non-serializable object type 'Andrew.InterfacesXLANGs.Components.IOrchestrationHelper orchestrationHelper' can only be declared within an atomic scope or service C:\Documents and Settings\v-anriv\My Documents\Visual Studio 2005\Projects\InterfacesXLANGs\InterfacesXLANGs\SubProcess.odx 46 66
Now, if you look into the cause of this error it is quite simple. BizTalk is a reliable messaging and orchestration server; the mechanism for achieving this reliability is that the state of messages and orchestrations is persisted to the Message Box database at runtime, either at persistence points (send ports, timeouts, exiting atomic scopes) or when the service decides to save the state to manage load. This is where the issue lies. In order to save the state of a variable it must be marked as serializable. When an orchestration hits a persistence point it serializes all of its variables and saves the data into the database. When the orchestration is "rehydrated", the state is deserialized and the processing can continue.
I mentioned scopes just above. Atomic scopes are a special case in BizTalk. These are the scopes in which an atomic (MSDTC) transaction is running. Obviously, in order to marshal the resources for such a transaction the orchestration must remain in memory during the processing of an atomic scope. This means that the scope must complete, or if it fails half way through BizTalk will assume that the work in the atomic scope has not been done, and will attempt to re-run it when the orchestration is started.
A side-effect of atomic scopes is that variables that are defined in an atomic scope will never be persisted to the database as they will always be in memory until the scope is complete. Because of this, it is possible to define a variable that is a non-serializable class.
As you can imagine, when a BizTalk host is running an orchestration t is just like any process executing code. However, when a persistence point is reached there is a double-hit on the performance as the state is serialized and is then saved into the message box database as a recoverable state point. This increased the latency of the orchestration considerably, and if throughput performance is an issue then you should minimise the number of persistence points. If you are more concerned with reliability then it's not such a bad thing.
If you look at the classes I defined they were all marked as serializable, so they could all happily exist in BizTalk orchestrations. However, because the variable was defined to use the interface, the compiler did not know if the class that would implement the interface would also be marked as serializable, therefore it generated an error.
The Solution, and some words of warning
In order to allow the BizTalk compiler to be fooled into accepting the interface, you need to declare the variable as the base class, and mark the base class as serializable. But be careful, if you do anything in your subclasses to make them non-serializable then there will be some unfortunate unintended consequences when the object is instantiated by the factory and loaded into the orchestration state.
Summary
I have used an example where an interface is used in a declaration in BizTalk to illustrate how BizTalk manages orchestration state through serialization of the orchestration variables. If you think about why and where orchestrations serialize and persist / dehydrate / rehydrate you will also start to get a grip on the factors that affect orchestration performance, and you can alter your designs to suit.
Wednesday, October 14, 2009
Just read this somewhere....
Thursday, October 08, 2009
Reminder : Fusion Log Viewer
C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\ FUSLOGVW.exe
You'll get a view of all assembly load failures, which is really useful with systems that dynamically load stuff from the GAC at runtime such as BizTalk.
Wednesday, October 07, 2009
BizTalk Error: Failed while delivering a message to a service instance. Message details follow.
- (Normal functionality): Orchestration extracts an entity from the data access layer, and uses a Start Orchestration shape to launch another orchestration, passing the entity as a parameter.
- (Error functionality): The second orchestration shows as started in the BizTalk Admin Console, it can be viewed in Orchestration Debugger, but it never starts processing even its first shape. (The event log blurb will be at the end of the post, because it's a bit bloaty and will detract from the commentary).
Saturday, October 03, 2009
BizTalk Multi-Part Messages and Serialization
- The system batch-processes BACS payments onto a ledger. Once per day input files come from a mainframe system and the payments need to be loaded into the ledger.
- An SSIS process decodes the files into a staging database location.
- The payments are extracted from the database for transmission to the ledger. This is done using BizTalk.
- The payments are split into batches and transmitted to the ledger.
- The ledger responds asynchronously with a message that describes the success / failure of the payment transaction.
- Payments that ultimately fail get written into a SQL table.
- Once per day, when processing of the payments is complete, the failed payments are extracted into a BACS file using an SSIS process.
- Bug was raised against the SSIS developer who wrote the output package. He unit tested the extraction process and verified that the value was being written correctly.
- The bug was then assigned to the developer who wrote the data access layer that writes the failed payments into the output staging table. He then verified that the amount values get written correctly into the database.
- The bug was then assigned to the BizTalk team and that meant that me, being one of the BizTalk architects with an overview of the entire process, was called in to look at the issue.
- The first thing I did was to attach a debugger onto the BizTalk hosts, so that I could look at the actual values being passed through the system. First, I debugged the orchestration that writes out the failed payments. I verified that the amount being written by BizTalk was zero - thus confirming that there was no issue with the data access code.
- I then debugged the orchestration that receives the failed payments and verified that the payment amount was non-zero. This meant that somewhere between receiving the payment and writing the payment out the value was being set to zero - but how?
- .Net objects can be used as part of multi-part message types; this improves the maintainability of your orchestrations and also allows context information to be written onto .Net objects.
- .Net objects, when assigned to a message part, are XML serialized when they are written to the message box. For this purpose, they must be XML serializable. It is easiest to generate these classes from an XML schema.
- Be careful that your .Net object serializes as you expect, because if it doesn't you can get unexpected and unexplained issues in your solution.