Skip to content
Community Question

How can developers use the Dataverse SDK to perform transactional operations across multiple records?

Share knowledge. Learn from experts. Build together.

Question

How can you ensure multiple Dataverse operations succeed or fail together? Explore how the Dataverse SDK and transaction mechanisms can be used when creating, updating, or deleting related records. Understand transaction boundaries, consistency, error handling, and rollback considerations. This is an important concept for developers building reliable enterprise Dataverse solutions.
60 Views Community Discussion

Answers

When a business operation involves several Dataverse records, one of the most important design questions is:

Should these changes succeed together, or is partial success acceptable?

If the business requirement is all-or-nothing, the Dataverse SDK provides ExecuteTransactionRequest.

For example, imagine an order-processing operation that needs to:

  • Create an Order
  • Create Order Lines
  • Update Inventory-related information
  • Create an audit record

If the Order and Order Lines are created but a later operation fails, the system could be left in an inconsistent state.

A transaction allows the application to treat these operations as one logical unit of work.

The Dataverse transaction model

With the Dataverse SDK for .NET, developers can place multiple organization requests into an ExecuteTransactionRequest.

Conceptually:

Application
    |
    | ExecuteTransactionRequest
    v
+--------------------------------------+
| Dataverse Transaction                |
|                                      |
|  Create Account                      |
|  Create Contact                      |
|  Update Opportunity                  |
|  Create Audit Record                 |
|                                      |
+--------------------------------------+
          |
          | All succeed
          v
       COMMIT

If one fails
          |
          v
       ROLLBACK

Microsoft documents ExecuteTransactionRequest specifically for executing multiple requests within a single database transaction. The requests are processed in the order supplied, and if one fails, the changes made within the transaction are rolled back. The returned fault identifies the request index that caused the failure.

Basic C# example

A simplified example looks like this:

var transaction = new ExecuteTransactionRequest
{
    Requests = new OrganizationRequestCollection(),
    ReturnResponses = true
};

transaction.Requests.Add(
    new CreateRequest
    {
        Target = new Entity("account")
        {
            ["name"] = "Contoso Ltd"
        }
    });

transaction.Requests.Add(
    new CreateRequest
    {
        Target = new Entity("contact")
        {
            ["firstname"] = "John",
            ["lastname"] = "Smith"
        }
    });

var response =
    (ExecuteTransactionResponse)serviceClient.Execute(transaction);

The important point is not the syntax. The important point is the transaction boundary.

If the second operation fails, the first operation does not remain committed as an independent change.

ExecuteTransactionRequest vs ExecuteMultipleRequest

This distinction is extremely important in interviews and real projects.

RequirementExecuteTransactionRequestExecuteMultipleRequest
Multiple requestsYesYes
Single transactionYesNo
Rollback all changes on failureYesNo
Useful for atomic business operationYesNot the primary purpose
Useful for reducing network overheadYesYes
Ordering of requestsPreservedPreserved
Suitable for bulk processingSometimesCommon scenario

ExecuteMultipleRequest is primarily designed to submit multiple requests efficiently. Microsoft explicitly distinguishes it from a single transactional unit.

So don't automatically choose ExecuteMultipleRequest simply because you have many records.

The question should be:

Do I need throughput, or do I need atomicity?

Sometimes the answer is neither. For very large workloads, asynchronous processing, integration pipelines, or Dataverse-native bulk patterns may be more appropriate.

A real-world example

Consider a Dynamics 365 Customer Service solution.

When a high-priority escalation is created, the business wants to:

  1. Create the escalation record.
  2. Update the Case.
  3. Create an escalation audit record.
  4. Create a related task.

Suppose step 4 fails.

If the business requires the entire operation to be atomic, the first three changes should not remain committed independently.

That is a transaction problem.

Business Operation
       |
       v
Create Escalation
       |
       v
Update Case
       |
       v
Create Audit
       |
       v
Create Task
       |
       +---- Failure?
               |
             YES
               |
               v
          Rollback

Where developers often make mistakes

Treating ExecuteMultiple as a transaction

This is probably the most common conceptual mistake.

A batch of requests is not automatically an atomic transaction.

Making the transaction unnecessarily large

A transaction should represent a meaningful business unit of work.

Don't put thousands of unrelated operations into one transaction simply because the API allows multiple requests.

Large transactional units can increase contention, duration and failure impact.

Mixing unrelated business processes

For example:

Create Customer
Create Invoice
Update Inventory
Create Marketing Campaign
Update Analytics

These may belong to different business processes.

A transaction should normally represent a coherent business invariant.

Ignoring idempotency

Transactions protect consistency inside the transaction boundary, but they don't automatically make an entire distributed workflow idempotent.

For example:

Dataverse Transaction
        |
        v
Commit
        |
        v
External API call
        |
        v
Failure

The Dataverse transaction cannot magically roll back an external system that has already accepted a request.

This becomes an important architecture distinction:

Database transaction ≠ distributed transaction.

For cross-system workflows, consider asynchronous messaging, correlation IDs, retry policies, compensation, and idempotency.

Important SDK consideration

Microsoft recommends the Dataverse SDK for .NET and the ServiceClient for client applications. Plug-ins and custom workflow activities have different runtime considerations.

Therefore, don't simply copy an application-level transaction pattern into every plug-in scenario.

Always consider:

  • execution pipeline stage
  • transaction boundaries
  • plug-in timeout
  • synchronous vs asynchronous execution
  • number of operations
  • external calls
  • retry behavior
  • failure recovery

Enterprise design principle

A good design question is:

What business invariant must never be partially committed?

That invariant should influence where the transaction starts and ends.

For example:

Order Creation
    |
    +-- Customer validation
    |
    +-- Order creation
    |
    +-- Order lines
    |
    +-- Financial validation
    |
    +-- Commit

This is much better than simply saying:

"I have five records, so I'll use a transaction."

The transaction should be driven by business consistency, not record count.

Key points

For Dataverse development:

  • Use ExecuteTransactionRequest when multiple Dataverse operations must succeed or fail together.
  • Use ExecuteMultipleRequest when batching/throughput is the primary requirement and atomicity is not required.
  • Keep transaction boundaries aligned with business invariants.
  • Don't confuse database transactions with distributed transactions.
  • Design for idempotency when external systems are involved.
  • Consider execution context and plug-in constraints before choosing the pattern.

Your Answer

Connect