Introduction

BizTalk is well-known for its persistence engine and ability to handle long-running, stateful workflows — from multi-day approval processes to complex supply chain transactions.
But with great state comes great responsibility: if implemented carelessly, these workflows can turn into sluggish, resource-hogging monsters.

In this post, we’ll walk through:

  1. What “highly stateful” means in BizTalk
  2. The pitfalls that slow them down
  3. Best practices to keep them performant
  4. A sample implementation pattern

1. What “Highly Stateful” Means in BizTalk

A highly stateful workflow:

  • Keeps a correlation set alive for hours, days, or even weeks.
  • Waits for multiple related messages (scatter/gather patterns).
  • Persists data between processing steps.
  • Handles compensation logic for failures.

Example scenario:
A Global Purchase Order Approval process:

  1. Receive initial PO.
  2. Wait for all subsidiary approvals.
  3. Aggregate results and send final confirmation.

BizTalk Orchestration Lifecycle

The diagram below shows when BizTalk persists state:

Receive --> Persist --> Process --> Persist at Wait Points --> Process Next Step --> Persist Before Sending

Persistence points are the performance cost centers — avoid adding more than you need.


2. Common Pitfalls

PitfallImpact
Too many persistence pointsSlows throughput dramatically
Large message persistenceBloats the MessageBox database
Unnecessary orchestration shapesIncreases dehydration/re-hydration overhead
Overusing correlation setsMore DB work per message
Holding messages too longLarger suspended queue, more DB growth

3. Performance Best Practices for Stateful Workflows

A. Reduce Persistence Points

  • Avoid unnecessary Suspend, Listen, or extra Receive shapes if a port filter can do the work.
  • Combine multiple decisions into one Decide block.

B. Use Message References, Not Copies

Instead of duplicating messages, use MessageRef pattern:

// Instead of creating a full copy:
msgCopy = msgOriginal; // This still makes a copy internally

// Use direct assignment where possible:
msgOriginal(*) = msgTransformed(*);

This reduces message size and persistence cost.

C. Offload Large Payloads Early

If the stateful part only needs metadata:

  1. Store the large payload in an external store (SQL, Blob storage).
  2. Keep only the reference (URL, ID) in BizTalk.

D. Use Correlation Wisely

  • Define the smallest possible correlation set.
  • Avoid correlation on large context properties (e.g., entire XML node values).

E. Minimize Orchestration Shapes

Fewer shapes = fewer persistence checkpoints.


4. Implementation Example

Let’s say we’re building a 3-step loan approval workflow that waits for:

  • Customer Documents
  • Credit Check
  • Manager Approval

Diagram: Workflow Flow

[Receive Initial Loan Request]
        |
  [Fan-out Request]
        |
<Wait for all 3 Responses>
        |
[Aggregate + Final Decision]
        |
 [Send Final Approval/Reject]

Step-by-Step BizTalk Orchestration

Step 1: Receive and Initialize Correlation

// Declare Correlation Set on LoanID
CorrelationSet LoanCorrSet;

// Receive initial loan request
Receive_LoanRequest.Activate = true;
InitializeCorrelation(LoanCorrSet);

Step 2: Parallel Listening for Responses

// Listen shape with parallel branches
Listen(
    Receive_CustomerDocs.FollowCorrelation(LoanCorrSet),
    Receive_CreditCheck.FollowCorrelation(LoanCorrSet),
    Receive_ManagerApproval.FollowCorrelation(LoanCorrSet)
);

Step 3: Aggregate Results Without Copying Messages

// Aggregate into a single decision message
msgDecision(*) = msgCustomerDocs(*);
msgDecision(*) = msgCreditCheck(*);
msgDecision(*) = msgManagerApproval(*);

Step 4: Send Decision

Send_FinalDecision(msgDecision);

Diagram: Persistence Points Optimized

[Receive_LoanRequest] --> PERSIST
[Listen for 3 Messages] --> PERSIST (only once per message arrival)
[Send_FinalDecision] --> PERSIST (final)

By designing it this way:

  • Only 3 main persistence points exist (instead of 6–8 in naive implementations).
  • Large payloads are kept outside orchestration state.

Summary

Highly stateful workflows are BizTalk’s superpower — but they come with a cost.
To keep them fast and maintainable:

  • Minimize persistence points
  • Keep payloads small
  • Use correlation efficiently
  • Avoid unnecessary orchestration shapes

By applying these practices, you’ll build workflows that can run for weeks without turning your MessageBox into a black hole.

Rule of Thumb: Every extra persistence point is a debit from your performance account — spend wisely.


Views: 9

Implementing a Highly Stateful Workflow in BizTalk – Without Killing Performance

Johannes Rest


.NET Architekt und Entwickler


Beitragsnavigation


Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert