Consuming a BizTalk hosted WCF Service with InfoPath 2007

Consuming a BizTalk hosted WCF Service with InfoPath 2007

I recently built a POC that wrapped an SAP RFC call in a WCF Service exposed by BizTalk. I exposed schemas as WCF services instead of opting for exposing the Orchestration as a WCF Service. The purpose of the Service was to validate a utility meter’s status inside of SAP.  Some of the statuses may include active/inactive/meter not found.  The RFC that I used is called RFC_Read_Table.  This is a pretty generic, out of box,  RFC that allows you to query SAP tables.  The RFC is fairly complex due to a lack of good documentation available.  Perhaps I am just not part of the secret SAP consultant’s club where you can actually get useful documentation.  I plan on documenting my findings in an upcoming post so that other people do not have to endure the pain I went through in order to get it working.

 

One of the benefits of InfoPath is the ability to consume a web service (asmx).  I was pleasantly surprised that InfoPath can also consume some  WCF endpoints(.svc).  The endpoint type that I exposed was based on the basicHttpbinding which happens to be one of the more interoperable bindings.  At this point, the SOAP adapter has been identified as an Adapter that will be removed in an upcoming release of BizTalk.  The idea behind this is that people should be moving to the WCF adapter.  There are some gaps between the SOAP and WCF adapter, which is outside the scope of this post, but my advice would be if you can use the WCF Adapter then you should.  If you cannot, due to a limitation, then you should provide this feedback to Microsoft so they can either enhance the WCF adapter or hold off on removing the SOAP adapter.

 

The InfoPath service consumption wizard is fairly straight forward with the exception of  “how the form works with the Web Service”.  The 3 options that you do have include:

  • Receive and submit data
  • Submit data
  • Receive data

 

When I think of a client consuming a Web Service, I think in terms of the client providing a Request message and the Server providing a Response.  With this in mind, I decided to use the “Submit data” option.  What I ran into is that I could submit data to my BizTalk Service, BizTalk would process the request and provide a response but nothing was being updated in my form.  I discovered that I needed to use the “Receive and submit data” option instead.  The description is counter intuitive as it implies I am receiving data first then I am submitting it.  Perhaps if Microsoft would have called this option “Submit and receive data” this would have been a little clearer.

 

I have recently been teased by a few colleagues and friends about the amount of detail and screen shots that I have put in my blog posts.  At the risk of more torture,   here is a step by step guide of how I got this all working.

  • Design a Form Template

image

 

  • Select “Web Service’” and click OK

image

 

  • If you want to submit data to a service and use the response data in your form, select “Receive and submit data’”

image 

 

  • Provide the destination of your WSDL and click “Next”

image

  • The name of my operation is “ValidateMeter”, click “Next”

image

  • Thus far, the information that has been provided is related to the Web Service response so I have provided a name for this data connection that reflects this.

image

  • Since I am submitting data to this same service, I need to provide the WSDL URL again.

image

  • Once again I need to provide the operation that I will be communicating with.

image

  • The “ValidateMeter” operation has a single input parameter.  I need to specify which field from the request schema will be sent to the Web Service.  To do this I want to click on the following button: image 

 

image

  • Select the field from Schema

image

  • Click “Next” to proceed

image

  • I now need to provide a name for this data connection

image

 

  • At this point I have a blank canvas and I also have the ability to start dragging and dropping fields from my Web Service Request and Response schemas onto the canvas.

image

 

  • I have expanded, the “queryFields” node and have dragged the “MeterNumber” element onto the canvas.  If you recall the value that will be populated in this field will be sent as part of the Request message to the ValidateMeter Service.

image

  • When BizTalk provides the response from SAP, I want to display this value on the form.  In order to do this, I need to expand the “dataFields” node and select “MeterStatus” from the Web Service Response schema.

image

 

  • To test my form, I can click on the “Preview” button

image

  • I can now provide a Meter Number and click the “Run Query” button.  Within a couple seconds I will see my Meter Status text get populated.  In this particular instance, the Meter Number 123456 does not exist so the Meter Status text box is updated to reflects this.

image

No Intellisense with VS 2010 RC (and how to fix it)

No Intellisense with VS 2010 RC (and how to fix it)

[In addition to blogging, I am also now using Twitter for quick updates and to share links. Follow me at: twitter.com/scottgu]

Patrick recently posted about something he found odd when installing the VS 2010 RC – which was that code intellisense for C# wasn’t working.  When he pulled up Tools->Options and checked under the Text Editor->C# settings he noticed that the reason Intellisense wasn’t working was because his profile had them turned off – and he couldn’t understand why it was configured to be off by default:

image

Why does this happen?

The above situation occurs because:

1) When you run VS 2010 the first time on a machine that has had VS 2008 installed on it, it asks you if you want to import your existing VS 2008 profile settings.  By default this checkbox is checked – which means you by default automatically import your existing settings.

2) Some VS plugins – for example Resharper – turn off the built-in C# code intellisense within VS and instead replace it with their own implementation.  If you’ve installed Resharper on VS 2008, the above VS code intellisense profile settings are turned off.  When you import your existing profile during VS 2010’s first time run experience the code intellisense settings import over in a disabled state.  If you haven’t installed Resharper on VS 2010 (which is a separate install) – then by default you’ll end up with intellisense turned off.

How to Fix this?

Fixing this situation with the VS 2010 RC is pretty easy.  Just do one of two things:

1) Use the Tools->Options menu command, select the Text Editor->C# settings, and then check the two circled check boxes above (Auto-list members and Parameter information).  Intellisense will then be turned on and work fine.

or:

2) Install the version of Resharper that works with the VS 2010 RC. It then enables intellisense using its own mechanism.

We are modifying the profile import behavior in the final release of VS 2010

We’ve heard reports of a few people running into this – and since the behavior is pretty confusing we are modifying the profile import behavior with the final release of VS 2010 to avoid it.  If a plugin has turned intellisense off with VS 2008, by default when you import the profile into VS 2010 we will re-enable it.  This will ensure that on a clean VS 2010 install intellisense always works by default. 

Hope this helps,

Scott

BizTalk 2009: BizTalk Mapper – get value from last node

BizTalk 2009: BizTalk Mapper – get value from last node

I ran into a situation where I needed to get the last value from a re-occurring node that SAP was returning.

In order to extract the last record, I utilized the Record Count functoid and fed that value into the Index functoid. The Index functoid is also fed with the value from the “WA” element that I am really interested in. The result is then passed to a String Concatenate functoid where the data is enriched before being assigned to the destination document.

Day-long Azure Conference in San Diego, March 6th

The San Diego .NET User Group will be hosting our first Azure day-long conference on March 6th. This first one will be more overview level, we’re planning at least one other which will be more focused and deeper for later this year, and then perhaps more after that. For this first one, we will be covering:

 

  • Azure Intro (David Chou)
  • Azure Development (Daniel Egan)
  • SQL Azure (Lynn Langit)
  • Azure AppFabric (Brian Loesgen)

 

And yes, the way it turned out, all speakers for this are from Microsoft, and David is a fellow co-author from the oh_so_close_to_done_now book I’ve been involved with for quite some time. “SOA with .NET and Windows Azure”.

These conferences are usually a lot of fun and great investments, and this one in particular will be a great way to jump-start your Azure knowledge, or fill in some gaps you may have.

The event page with further details is here. As usual, great discounts for user group members.

Hope to see you there!

Using XSLT 1.0 to summarize a node-set with comma separated values

Pure XSLT is very powerful but it definitely has its weaknesses (I’ve written about how to extend XSLT using mapping and BizTalk previously here) … One of those are handling numbers that uses a different decimal-separator than a point (“.”).

Take for example the XML below

<Prices>
  <Price>10,1</Price>
  <Price>10,2</Price>
  <Price>10,3</Price>
</Prices>

Just using the XSLT sum-function on these values will give us a “NaN” values. To solve it we’ll have to use recursion and something like in the sample below.

The sample will select the node-set to summarize and send it to the “SummarizePrice” template. It will then add the value for the first Price tag of the by transforming the comma to a point. It will then check if it’s the last value and if not use recursion to call into itself again with the next value. It will  keep adding to the total amount until it reaches the last value of the node set.

<xsl:template match="Prices">
  <xsl:call-template name="SummurizePrice">
    <xsl:with-param name="nodes" select="Price" />
  </xsl:call-template>
</xsl:template>

<xsl:template name="SummurizePrice">
  <xsl:param name="index" select="1" />
  <xsl:param name="nodes" />
  <xsl:param name="totalPrice" select="0" />

  <xsl:variable name="currentPrice" select="translate($nodes[$index], ',', '.')"/>

  <xsl:choose>
    <xsl:when test="$index=count($nodes)">
      <xsl:value-of select="$totalPrice + $currentPrice"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:call-template name="SummurizePrice">
        <xsl:with-param name="index" select="$index + 1" />
        <xsl:with-param name="totalPrice" select="$totalPrice + $currentPrice" />
        <xsl:with-param name="nodes" select="$nodes" />
      </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>

</xsl:template>

Simple but a bit messy and nice to have for future cut and paste 😉

BizTalk: Compensation Model

BizTalk: Compensation Model

BizTalk: Compensation Model

Charles Young mentioned, the Compensation is one of the most under-used features of the BizTalk.
[“
BizTalk Server 2006: The Compensation Model
http://geekswithblogs.net/cyoung/articles/100424.aspx]
If you didn’t read his article, I would strictly recommend it. Next article to read is
[“
Transactions and Compensation Using BizTalk Server
http://blogs.msdn.com/richardbpi/archive/2006/12/06/transactions-and-compensation-using-biztalk-server.aspx]
by Richard Seroter.

There are still many questions in using Compensation in BizTalk.
%u00b7 What is the proper order of the Exception and Compensating blocks (handlers), Compensate shapes?
%u00b7 Do we have to rethrow the Exceptions?
%u00b7 Do we have to use Compensate shape for the current transaction or for the internal transactions?
%u00b7 What exactly does the Compensate shape?
%u00b7 What is the difference between Atomic and Long-Running transactions from the Compensation point of view?
Let’s start from the theory.
Compensation and Rollback
I have to use term the Rollback in this document. It is not from the BizTalk Documentation.
Data_1–> [Transaction: Data_1to2]–> Data_2
I use the Rollback term like the same term in the database transactions. Rollback means restoring all data to the point before transaction. It is completely automatic, atomic process. We cannot control rollback. Only one operation is possible, Start Rollback. It rolls back only the local orchestration data, orchestration variables and parameters.
The local orchestration data outside the transaction could be only Data_1 or Data_2. When Transaction is Committed, the data is Data_2. When Transaction is Rollbacked, the data automatically returns to the pre-transaction state, to the Data_1. We never get the Data_1to2 outside the Transaction. We all know this; it is ABC of the Transaction model.
But BizTalk is not a data base server as SQL Server and transaction in BizTalk is not a data base transaction. For example the Send shape inside transaction scope can send message to the external system and change data in this system. In general case BizTalk cannot automatically roll back this operation and won’t do this. We have to manually create a code to roll back the external changes. Atomic transaction might change the external system in the same way as Long-Running transaction. BizTalk helps us with managing this roll back procedure. We include the custom roll back code in the Compensation block. This code is invoked automatically by BizTalk or manually by a Compensate shape and the whole process called the Compensation.
Compensation it is not a Rollback. It is another process.
Compensation is a controlled process. Here is a typical example: code inside BizTalk transaction inserts rows in the database. BizTalk does not automatically rollback this operation. But it gives us possibility to implement [maybe] complex business process of deleting inserted rows. Plus, the last uncontrolled step of the Compensation is a Rollback. We implement some custom business process of compensation and then BizTalk invoke Rollback.
All Rollbacks and Compensations are initiated by an Exception. If an Exception is fired inside transaction, BizTalk invokes Rollback, but Compensation for this transaction is usually prohibited.
BizTalk invokes Rollback, but before that BizTalk invokes the Exception block of this transaction, if there is such block and if this block catches the Exception.
Note: Compensation block and Compensation shape are different things. Compensation shape is a method to call the Compensation block.
Atomic and Long-Running transactions
By design Atomic transaction should be used for the fast and simple procedures. The data before Atomic transaction is not persisted on the disk. Atomic transaction is quick that’s why it does not damage the total reliability. You can mention that Atomic transaction property the Timeout automatically set up to 60 sec, but not for the Long-Running transaction. Moreover only the Atomic transaction has the Property the Retry because it makes sense to automatically retry only the short process not the long one.
The likelihood of the system crash is bigger in the durations of hours and days than in seconds. That’s why data before Long-Running transaction persisted to disk. That’s why the orchestration data used in the Long- Running transaction must be serializable. That’s why the Long-Running transaction theoretically slower than Atomic transaction.
Note: Atomic transaction in BizTalk is not atomic in strict sense. It can include requests to the external processes, calls to the .NET classes, etc. Each of these processes could change something outside the orchestration and the transaction Rollback does not automatically roll back all these changes. It would be dangerous.
The Atomic transaction is short by definition. It cannot nest other transactions inside. The Atomic transaction is processed as a single unit of work. If Exception is fired inside the Atomic transaction, all we have to do is to roll back this transaction. And BizTalk makes this automatically. We cannot change this roll back process no matter what sort of Exception was fired.
Seems this is the main difference between n the Atomic and Long-Running transactions in BizTalk, how they behave in case of the internal Exception. Atomic transaction always automatically performs Rollback. We cannot avoid this Rollback and cannot do something else. Long-Running transaction could catch the Exception in the optional Exception block and process the rollback in specific custom code. But the Exception block cannot prevent the automatic Rollback. The Rollback occurs after executing the Exception block. If a Long-Running transaction does not have the Exception blocks it processes an Exception the same way as an Atomic transaction.
Compensations and Exceptions
Rule 1: Transaction block can get only one custom Compensation block.
Rule 2: If the Compensation block is not defined, the Transaction uses the default Compensation. Default Compensation is the Compensation for the current Transaction. That means the unwiring the Compensations for the nested Transactions and Rollback (restoring the Orchestration variables).
Rule 3: Firing an Exception is the only way to initialize the Compensation process.
Rule 4: Atomic transaction block cannot get the Exception block.
Rule 5: Long-Running transaction use the default Exception block for the “General Exception” if the custom Exception block for the “General Exception” is not defined. Default Exception block invokes the Compensation shape for current transaction and rethrow the Exception.
Rule 6: Compensation shape can be inserted only inside Exception block or Compensation blocks.
It seems obvious but anyway
We can include the Compensate shape nowhere but only in the Exception and Compensation blocks. We cannot start the compensation process arbitrary. No exception – no compensation! Sometimes we need to utilize the automatic compensation ability of the BizTalk in the ordinary business process. Firing Exception is not the ordinary situation; an exception should be always indicator of the error in process. But here we have to use exception, there are no other ways.
Rule 7: Transaction that fired the Exception processes a Rollback right after this Exception. We cannot compensate this transaction.*
*) As Charles Young mentioned here is a workaround for this rule (see the “Using Compensation Blocks on L-R Transactions” topic in his article), but you have to use undocumented features of the BizTalk. BizTalk is wisely trying to prevent compensating uncommitted transaction.
Standard compensation process (Example)
Let’s cover the standard compensation process.
Below is the simple orchestration with one LR nesting transaction (1—) and two nested transactions (11 and 12).
Second nested transaction fired the Exception.
Let see what is going on here:
1. Code generates the DivideByZeroException
2. The Exception is caught in the Exception block of the same Transaction.
3. The Exception is rethrown.
4. BizTalk rolls back the Transaction, that means it restore the orchestration variables and parameters.
5. The Exception is caught in the Exception block of the nesting, outer Transaction.
6. Calls to the Compensating of the nested Transactions in the revers order. Compensation of the 12 cannot be executed because this transaction was not Committed (completed).
7. Compensating of the 11 Transaction.
8. Exception is rethrown. Orchestration is suspended.
Why the Compensation blocks the Comp12 and Comp 1 were not executed? For different reasons.
Comp12 was not executed because Transaction the 12 was not committed but rollbacked and a try to call the Compensation in the C_Ex 1 block was skiped.
Comp1 was not executed because it could be called only from the outer, nesting transaction. We don’t have such transaction here.
The trace log was:
1 —
1 — 11…
1 — 11… 12…(1)
1 — 11… 12… >>> Exc 12 (2)
1 — 11… 12… <<< Exc 12 Rethrow Exception ******** (3) (4)
1 — 11… >>> C_Ex 1 (5)
1 — 11… >>> Comp 11 (6)
1 — 11… <<< Comp 11 (7)
1 — 11… <<< C_Ex 1Rethrow Exception ******** (8)
Below is the XLANGs code generated by BizTalk Orchestration Editor:
module GLD.Samples.Compensation
{
internal service longrunning transaction StandardCompensation
{
port implements PortType_1 Control_R;
message System.Xml.XmlDocument msg_XmlDocument;
System.Int32 var_int;
System.String var_State;
body ()
{
activate receive (Control_R.Operation_1, msg_XmlDocument);
var_int = 0;
var_State = “”;
scope longrunning transaction tx_1
{
System.Int32 var_IntLevel1;
body
{
var_IntLevel1 = 0;
var_State = “1 — “;
System.Diagnostics.Trace.WriteLine(var_State);
scope longrunning transaction tx_11
{
body
{
var_State = var_State + “11… “;
System.Diagnostics.Trace.WriteLine(var_State);
}
compensation ()
{
System.Diagnostics.Trace.WriteLine(var_State + “>>> Comp 11”);
System.Diagnostics.Trace.WriteLine(var_State + “<<< Comp 11”);
}
}
scope longrunning transaction tx_12
{
body
{
var_State = var_State + “12… “;
System.Diagnostics.Trace.WriteLine(var_State);
// Exception!!!
var_int = var_int / System.Convert.ToInt32(“0”);
}
exceptions
{
catch
{
System.Diagnostics.Trace.WriteLine(var_State + “>>> C_Ex 12”);
System.Diagnostics.Trace.WriteLine(var_State + “<<< C_Ex 12 Rethrow Exception ********”);
throw;
}
}
compensation ()
{
System.Diagnostics.Trace.WriteLine(var_State + “>>> Comp 12”);
System.Diagnostics.Trace.WriteLine(var_State + “<<< Comp 12”);
}
}
}
exceptions
{
catch
{
System.Diagnostics.Trace.WriteLine(var_State + “>>> C_Ex 1”);
if (succeeded(tx_12))
{
compensate tx_12 ();
}
if (succeeded(tx_11))
{
compensate tx_11 ();
}
System.Diagnostics.Trace.WriteLine(var_State + “C_Ex 1Rethrow Exception ******** “);
throw;
}
}
compensation ()
{
System.Diagnostics.Trace.WriteLine(var_State + “>>> Comp 1”);
compensate tx_1 ();
System.Diagnostics.Trace.WriteLine(var_State + “<<< Comp 1”);
}
}
}
}
}
The uncear points in the Compensation Model
To me there are several confusing things in the Compensation model.
First, the Compensation blocks are called outside. Event to call the Compensation comes outside! It is pretty unusual from the developer experience. One more time: the Compensation block is called outside. We are waiting that methods start from the first operator, and the exceptions catch blocks are placed in the end of code. The Exception blocks in the Orchestration are placed as we are waiting for, in the end of the code. Compensation blocks placed in the same place but worked in opposite manner. It is unintuitive. Now the similar graphic presentation of the Exception and Compensation blocks mixed with different behaviour of the Exception and Compensation blocks. It is misleading.
Second, Rollbacks and Compensation are kind of unsynchronized. I will tell about this in the next sample.
Compensation Model process (Example)
Let’s cover the more complex compensation process.
This is the transaction tree:
Below is the orchestration picture. Nesting transaction was implemented in nested loops.
Exception was fired in the 1222 transaction.
The trace log was:
——————————- 5 —————————-
1000***
1000*** 1100===
1000*** 1100=== 1110—
1000*** 1100=== 1110— 1111…
1000*** 1100=== 1110— 1111… 1112…
1000*** 1100=== 1110— 1111… 1112… 1120—
1000*** 1100=== 1110— 1111… 1112… 1120— 1121…
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122…
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… 1200===
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… 1200=== 1210—
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… 1200=== 1210— 1211…
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… 1200=== 1210— 1211… 1212…
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… 1200=== 1210— 1211… 1212… 1220—
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… 1200=== 1210— 1211… 1212… 1220— 1221…
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… 1200=== 1210— 1211… 1212… 1220— 1221… 1222…
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… 1200=== 1210— 1211… 1212… 1220— 1221… 1222…******* Throw exception(1)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… 1200=== 1210— 1211… 1212… 1220— 1221… >>> C_Ex 3(2)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… 1200=== 1210— 1211… 1212… 1220— 1221… >>> Comp 4(3)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… 1200=== 1210— 1211… 1212… 1220— 1221… <<< Comp 4(4)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… 1200=== 1210— 1211… 1212… 1220— 1221… <<< C_Ex 3 ******* ReThrow exception(5)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… 1200=== 1210— 1211… 1212… >>> C_Ex 2(6)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… 1200=== 1210— 1211… 1212… >>> Comp 3(7)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… 1200=== 1210— 1211… 1212… >>>Comp 4(8)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… 1200=== 1210— 1211… 1212… <<< Comp 4(9)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… 1200=== 1210— 1211… >>> Comp 4(10)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… 1200=== 1210— 1211… <<< Comp 4 (11)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… 1200=== 1210— 1211… 1212… <<<Comp 3(12)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… 1200=== 1210— 1211… 1212… <<< C_Ex 2 ******* ReThrow exception(13)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… >>> C_Ex 1(14)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… >>> Comp 2(15)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… >>> Comp 3(16)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… >>> Comp 4(17)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… <<< Comp 4(18)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… >>> Comp 4(19)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… <<< Comp 4(20)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… <<< Comp 3(21)
1000*** 1100=== 1110— 1111… 1112… >>> Comp 3(22)
1000*** 1100=== 1110— 1111… 1112… >>> Comp 4(23)
1000*** 1100=== 1110— 1111… 1112… <<< Comp 4(24)
1000*** 1100=== 1110— 1111… >>> Comp 4(25)
1000*** 1100=== 1110— 1111… <<< Comp 4(26)
1000*** 1100=== 1110— 1111… 1112… <<< Comp 3(27)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… <<< Comp 2(28)
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122… <<< C_Ex 1(29)
……………………………………………………………..
1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122…
Picture of whole compensation process:
As an initial exception (1) is fired, there are several stages in the compensation process. A catch block follows after each exception, then compensations (blue arrow) and rollbacks (green arrow) for nested transaction(s). Each compensation is followed by a rollback with nested compensations and rollbacks in between.
For example, an Exception (5) in the Catch Exception block the “C_Ex 3” of the transaction 1220 is caught into the Catch Exception block (6) of the Transaction 1200, then follows the Compensation “Comp3” for the Transaction 1210 (7), the Compensation (8) and the Rollback (9) for the Transaction 1212, the Compensation (10) and the Rollback (11) for the Transaction 1211, the Rollback (12) for the Transaction 1210.
You can mention one interesting detail in the whole compensation process: All compensation blocks were called and all compensation code inside was invoked. But the orchestration data was not returned to the initial state. The orchestration data was roll backed only for the transaction branch where exceptions were fired, for the transaction 1200 and nested transactions. We could predict the roll backed data would be the “” but it is “1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122…”
Is it a bug in BizTalk?
Seems the compensation process is tuned up only for the “default” compensation model for some reason. In this model each implicit Exception block is finished by a Throw Exception operator. As you can remember the Default Exception block invokes the Compensation shape with current transaction and rethrow an initial Exception. If we follow this model we have got a predictable rollback process.
In the preceding example we have to nest the Transaction 1000 in outer Transaction and add a Throw Exception operator in “C-Ex 1” Exception block. In this case the data would be roll backed to the “” value in this outer transaction.
Rule 7: The orchestration data is roll backed to the initial point of the transaction where the last exception is rethrown.
For example, the last exception was rethrown in the Transaction 1200. The initial data for this Transaction was “1000*** 1100=== 1110— 1111… 1112… 1120— 1121… 1122…”. The orchestration data was roll backed to this value, not to the initial data for the outer compensated Transaction 1000.
Conclusion
Let’s summarize how to create the standard compensation process.
1. Define the Compensation blocks for all transaction you want to be compensated. This is the most chalenging task.
2. Define the Exception blocks where the Exception(s) should be cought.
3. Add the Compensate shape(s) to this Exception block. Define what transaction you want to compensate. The standard way is to define a current transaction. All nested transactions would be compensated automaticaly in the right order.
4. If you need a predictable rollback process for the orchestration data, rethrow an Exception in each Exception block where you added the Compensate shape.


SQL Server does not exist or access denied : 08001 when deploying Microsoft.BizTalk.ESB.BAM.Exceptions.xml

SQL Server does not exist or access denied : 08001 when deploying Microsoft.BizTalk.ESB.BAM.Exceptions.xml

When deploying the Microsoft.BizTalk.ESB.BAM.Exceptions.xml BAM activity (as part of the Core ESB Toolkit install) we ran into this error:

OLE DB error: OLE DB or ODBC error: DBNETLIB][ConnectionOpen (Connect()).]SQL Server does not exist or access denied : 08001

Errors in the high-level relational engine. A connection could not be made to the data source with the DataSourceID of ’bam_ExcByApplication’, Name of ’bamExcByApplication’

The issue was that we used a SQL Server Alias while configuring BizTalk to point to our backend SQLservers. This apparently led to the alias name being embedded into the Analysis Services artifact generation when we tried to deployed the BAM Activity. We had the SQL Server Alias on the two BizTalk application servers. We did not have it on the two Analysis Services cluster nodes. Once we added it to the SSAS nodes we were able to successfully deploy the activity.