Playing with Persistence Points in Biztalk Orchestrations
Introduction
BizTalk uses the **persistence points to save the orchestrations state to the SQL Server, **allowing BizTalk to recover from this points when an error happens.
This is very important when we design our orchestrations because each persistence point involves a lot of SQL Server work and affects the performance.
Also, we need to understand the persistence points in our orchestrations because when an orchestration is suspended and we resume it, the orchestration starts the work again from the last persistence point achieved.
Which are this Persistence Points?
In a usual scenario, the persistence points in an orchestration are in these points:
1) End of a transactional scope (atomic or long running)
2) At the Send Shape, except when the shape is inside of an atomic transaction.
3) At the end of the orchestration
4) Executing other orchestrations with Start Orchestration shape.
Also in these points:
5) When an orchestration instance is suspended.
6) When the orchestration instance is finished.
7) When the system shutdowns in a controlled manner.
8) When the engine determines it wants to dehydrate.
These persistence points induce latency in the execution of our orchestration because BizTalk has to save the state at this points on database and this trips to the SQL Server increase the latency of the execution
Testing
Now, let's play with Persistence Points and Resume Instances feature.
The application will be very simple, an orchestration that invokes a .Net library that divide the input where we have two code versions.
Version 1 fails if we send 0 as second parameter:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PersistencePoints.Libraries
{
[Serializable]
public class DivideFunction
{
public double DivideMethod (int num1, int num2)
{
return num1 / num2;
}
}
}
Version 2 checks if we send 0 as second parameter, then returns 0 and not fail:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PersistencePoints.Libraries
{
[Serializable]
public class DivideFunction
{
public double Divide(int value1, int value2)
{
if (value2 == 0)
return 0;
return value1 / value2;
}
}
}
Without Persistence Points between Receive and Send
First we will see the BizTalk behaviour when executing an orchestration without Persistence Points between Receive and Send
https://3.bp.blogspot.com/-5Cc2S3qzFwo/Wnhc61dOUxI/AAAAAAAAA2c/MGP9r60Dsdg5MOOPzujkiKJGm6DsB8qtgCLcBGAs/s640/NoPersistencePoints.png
This orchestration is very simple, only we invoke the .NET class on "Call Divide Component" Shape, with the input values that we receive on the Input Message.
In this scenario, if there are any error after receive shape, when we Resume the instance, we restart the orchestration from the beginning.
First we will try with my Version 1 of the C# component. If I send a correct input:
Value 1 = 10
Value 2 = 10
The execution between traces is this:
https://3.bp.blogspot.com/-OWimveK2sJs/WnhpVdqGHVI/AAAAAAAAA2s/EpLe82_OHnE_Zwofe9xB_NGRmokG4IseQCLcBGAs/s400/NoPersistencePoints%2B-%2B1.png
If we send this input message:
Value 1 = 10
Value 2 = 0
The orchestration will fail and the instance will be Suspended after the receive:
https://3.bp.blogspot.com/-zn6RAuAuFP8/WowZRWsvLJI/AAAAAAAAA3U/0k1rAZyk5Po0VvvdulQzPj5gvzCNh5TtwCLcBGAs/s400/ErrorLog.png
At this moment, if we update the GAC with the Version 2 of the C# component, restart de Host Instance and Resume the Instance, it will restart the work at the beginning:
https://1.bp.blogspot.com/-5IuRYK3plaI/WowZVhToyaI/AAAAAAAAA3Y/yBQNvxyLPf4BkqQEK5G-pLjirfySkAE9gCLcBGAs/s400/CorrectLog.png
Send Shape between Receive and Send
Let's see how is the BizTalk behaviour when we add a Send Shape between Receive and Send. This new shape is a persistence point in the middle of our orchestration.
https://2.bp.blogspot.com/-JP-dOz54yB4/WowgiLsfFbI/AAAAAAAAA3s/sMz3O6vknGMiyxWrDxnpOmdOn5iOjTdyACLcBGAs/s640/Scenario2.png
In this scenario, if there are any error after Receive_1 and before Send_1, when we Resume the instance, we restart the orchestration from the beginning. If the error is after Send_1, when we Resume the instance, it will continue after Send_1.
If we try with **Version 1 of the C# component **with incorrect input:
https://3.bp.blogspot.com/-hnPZ3YB80HE/Wowik5t6PYI/AAAAAAAAA34/W9gnfip2lGEobOqscFOiBPh_fkU2eEvAgCLcBGAs/s400/ErrorLog2.png
At this moment, if we update the GAC with the Version 2 of the C# component, restart de Host Instance and Resume the Instance, it will continue the execution after Send_1:
https://1.bp.blogspot.com/-Vz2NhoAdy9E/WowipdLuvII/AAAAAAAAA38/M3yIn1hOdxE61373VAD7DIezS9Eiva__gCLcBGAs/s400/CorrectLog2.png
Send Shape between Receive and Send in an atomic transaction scope
If we add a Send Shape between Receive and Send in a atomic transaction scope, the new Persistence Point is not the Send Shape added, now is the end of the Atomic Scope.
https://1.bp.blogspot.com/-4ByRR0ek85M/WowlaAATtgI/AAAAAAAAA4U/IL-21nt3AowRfwclRWDgMt64ol5t3pEJgCLcBGAs/s640/Scenario3.png
In this scenario, if there are any error after receive shape, when we Resume the instance, we restart the orchestration from the beginning.
If we use **Version 1 of the C# component **with incorrect input:
https://2.bp.blogspot.com/-E2L6KBsO7-E/WowlFCkw2OI/AAAAAAAAA4M/puF16Sfxc2QPDt_rS9bO03AD8nTOanBZgCLcBGAs/s400/ErrorLog3.png
At this moment, if we update the GAC with the Version 2 of the C# component, restart de Host Instance and Resume the Instance, it will restart the work at the beginning:
https://1.bp.blogspot.com/-mXDYMJnRI88/WowlOaUceJI/AAAAAAAAA4Q/lF7PG4fFX0srGQdQ4UP1IXYEe24WtevTQCLcBGAs/s320/CorrectLog3.png
Conclusion
We don't take care of Persistence Points usually when we are developing, but a bad orchestration design will introduce some unnecesary latencies and performance problems.
A typical example is if we have two Send Shapes together:
/en-us/biztalk/core/media/bts-trans-orch-fig2.gif
On the left we have two persistence points and on the right we have only one, then on the left we are doing an unnecesary trip to the SQL Server to save the state and obviously this affects the performance of our orchestrations.
See Also
A great place to start learning about the BizTalk product is BizTalk Server Resources on the TechNet Wiki
References
Information available at following websites was referred while writing this article.
- Using DebugView with BizTalk for debugging
- Understanding Persistence Points in Biztalk Orchestration
- Orchestration Handling of Suspended Messages