πŸ”’ Guided

Pre-launch preview. Authorised access only.

Incorrect code

Guided by A Guide to Cloud
Explore AB-900 AI-901 aws-aif-c01
Guided DP-420 Domain 1
Domain 1 β€” Module 11 of 11 100%
11 of 28 overall

DP-420 Study Guide

Domain 1: Design and Implement Data Models

  • Cosmos DB β€” The Big Picture Free
  • Designing Your Data Model Free
  • Partition Key Strategy Free
  • Synthetic and Hierarchical Partition Keys Free
  • Relationships β€” Embedding vs Referencing Free
  • SDK Connectivity and Client Configuration Free
  • SDK CRUD Operations and Transactions Free
  • SQL Queries in Cosmos DB Free
  • SDK Query Pagination and LINQ Free
  • Server-Side Programming Free
  • Transactions in Practice Free

Domain 2: Design and Implement Data Distribution

  • Global Replication and Failover
  • Consistency Levels: Five Choices, Real Trade-Offs
  • Multi-Region Writes and Conflict Resolution

Domain 3: Integrate and Move Data

  • Change Feed with Azure Functions and Processors
  • Analytical Workloads: Synapse Link and Fabric Mirroring
  • Data Movement: ADF, Kafka, and Spark Connectors

Domain 4: Optimize Query and Operation Performance

  • Indexing Policies: Range, Spatial, and Composite
  • Request Units and Query Cost Optimization
  • Integrated Cache and Dedicated Gateway
  • Change Feed Patterns: Materialized Views and Estimator

Domain 5: Maintain an Azure Cosmos DB Solution

  • Monitoring: Metrics, Logs, and Alerts
  • Backup and Restore: Periodic vs Continuous
  • Network Security: Firewalls, VNets, and Private Endpoints
  • Data Security: Encryption, Keys, and RBAC
  • Cost Optimization: Throughput Modes and RU Strategy
  • DevOps: Infrastructure as Code and Deployments
  • Exam Strategy and Cross-Domain Review

DP-420 Study Guide

Domain 1: Design and Implement Data Models

  • Cosmos DB β€” The Big Picture Free
  • Designing Your Data Model Free
  • Partition Key Strategy Free
  • Synthetic and Hierarchical Partition Keys Free
  • Relationships β€” Embedding vs Referencing Free
  • SDK Connectivity and Client Configuration Free
  • SDK CRUD Operations and Transactions Free
  • SQL Queries in Cosmos DB Free
  • SDK Query Pagination and LINQ Free
  • Server-Side Programming Free
  • Transactions in Practice Free

Domain 2: Design and Implement Data Distribution

  • Global Replication and Failover
  • Consistency Levels: Five Choices, Real Trade-Offs
  • Multi-Region Writes and Conflict Resolution

Domain 3: Integrate and Move Data

  • Change Feed with Azure Functions and Processors
  • Analytical Workloads: Synapse Link and Fabric Mirroring
  • Data Movement: ADF, Kafka, and Spark Connectors

Domain 4: Optimize Query and Operation Performance

  • Indexing Policies: Range, Spatial, and Composite
  • Request Units and Query Cost Optimization
  • Integrated Cache and Dedicated Gateway
  • Change Feed Patterns: Materialized Views and Estimator

Domain 5: Maintain an Azure Cosmos DB Solution

  • Monitoring: Metrics, Logs, and Alerts
  • Backup and Restore: Periodic vs Continuous
  • Network Security: Firewalls, VNets, and Private Endpoints
  • Data Security: Encryption, Keys, and RBAC
  • Cost Optimization: Throughput Modes and RU Strategy
  • DevOps: Infrastructure as Code and Deployments
  • Exam Strategy and Cross-Domain Review
Domain 1: Design and Implement Data Models Free ⏱ ~12 min read

Transactions in Practice

Apply transactional patterns to real scenarios β€” order processing with TransactionalBatch, inventory reservation with stored procedures, and cross-partition consistency with the Saga pattern.

Transactions in the real world

β˜• Simple explanation

Think of buying a coffee. Three things must happen: (1) your card gets charged, (2) the coffee is poured, (3) the receipt is printed. If the card fails, you don’t get coffee and no receipt is printed. That’s a transaction β€” all or nothing.

In Cosmos DB, you have three ways to get β€œall or nothing”: TransactionalBatch (simple, SDK-native), stored procedures (flexible, JavaScript), and Sagas (for cross-partition work where true transactions aren’t possible).

Cosmos DB offers ACID transactions within a single logical partition via two mechanisms (TransactionalBatch and stored procedures). For cross-partition work, you need the Saga pattern β€” a sequence of operations with compensating actions if something fails.

  • Pattern 1 β€” TransactionalBatch: Multiple SDK operations in one atomic call. Simple, typed, modern.
  • Pattern 2 β€” Stored procedure: JavaScript logic that reads, validates, and writes atomically. More flexible but harder to maintain.
  • Pattern 3 β€” Saga: Orchestrate operations across partitions or containers with compensating transactions for rollback. Not truly atomic β€” eventual consistency.

Pattern 1: Order processing with TransactionalBatch

πŸš€ Priya’s NovaSaaS billing system needs to atomically: create an order, create a payment record, and update the customer’s subscription status β€” all in the same tenant partition.

// All three items share the same partition key: /tenantId = "tenant-abc"
var order = new OrderItem
{
    Id = "ord-500",
    TenantId = "tenant-abc",
    Type = "order",
    Amount = 299.00m,
    Status = "confirmed",
    CreatedAt = DateTime.UtcNow
};

var payment = new PaymentItem
{
    Id = "pay-500",
    TenantId = "tenant-abc",
    Type = "payment",
    OrderId = "ord-500",
    Method = "credit-card",
    Status = "captured"
};

TransactionalBatchResponse batch = await container
    .CreateTransactionalBatch(new PartitionKey("tenant-abc"))
    .CreateItem(order)
    .CreateItem(payment)
    .PatchItem("sub-001", new[]
    {
        PatchOperation.Set("/status", "active"),
        PatchOperation.Set("/lastPaymentDate", DateTime.UtcNow.ToString("o"))
    })
    .ExecuteAsync();

if (batch.IsSuccessStatusCode)
{
    Console.WriteLine("Order, payment, and subscription updated atomically.");
}
else
{
    // ALL operations rolled back β€” nothing was written
    Console.WriteLine($"Transaction failed: {batch.StatusCode}");
    TransactionalBatchOperationResult failedOp = batch[batch.Count - 1];
    Console.WriteLine($"Failed operation: {failedOp.StatusCode}");
}

Why TransactionalBatch here: All items share /tenantId, the operations are simple CRUD, and we need atomicity. No JavaScript needed.

Pattern 2: Inventory reservation with stored procedure

Jake’s GlobeCart e-commerce platform needs a stored procedure that reads the current stock, checks availability, and reserves items β€” all atomically:

function reserveInventory(productId, quantity) {
    var context = getContext();
    var container = context.getCollection();
    var response = context.getResponse();

    // Step 1: Read current inventory
    var query = 'SELECT * FROM c WHERE c.id = "' + productId + '" AND c.type = "inventory"';
    var accepted = container.queryDocuments(container.getSelfLink(), query,
        function (err, docs) {
            if (err) throw new Error("Query failed: " + err.message);
            if (docs.length === 0) throw new Error("Product not found: " + productId);

            var inventory = docs[0];

            // Step 2: Check availability
            if (inventory.availableStock < quantity) {
                throw new Error("Insufficient stock. Available: " + inventory.availableStock +
                    ", Requested: " + quantity);
            }

            // Step 3: Reserve (atomic β€” if this fails, the read is also rolled back)
            inventory.availableStock -= quantity;
            inventory.reservedStock += quantity;
            inventory.lastReservedAt = new Date().toISOString();

            var replaceAccepted = container.replaceDocument(inventory._self, inventory,
                function (err) {
                    if (err) throw new Error("Reserve failed: " + err.message);
                    response.setBody({
                        success: true,
                        remainingStock: inventory.availableStock,
                        reservedQuantity: quantity
                    });
                }
            );

            if (!replaceAccepted) throw new Error("Replace not accepted");
        }
    );

    if (!accepted) throw new Error("Query not accepted");
}
// Calling from C#
var result = await container.Scripts.ExecuteStoredProcedureAsync<dynamic>(
    "reserveInventory",
    new PartitionKey("product-laptop-001"),
    new dynamic[] { "product-laptop-001", 2 });

Console.WriteLine($"Reservation: {result.Resource}");

Why a stored procedure here: We need a read-check-write pattern β€” read stock, validate, then write. TransactionalBatch can’t express conditional logic (it’s a flat list of operations). The stored procedure ensures no race condition between the read and write.

Pattern 3: Cross-partition Saga

πŸ“‘ Amara at SensorFlow needs to provision a new IoT device β€” which involves writing to three different containers with different partition keys:

1. Create device record      β†’ devices container (pk: /deviceId)
2. Assign to fleet            β†’ fleets container (pk: /fleetId)
3. Create monitoring config   β†’ configs container (pk: /deviceId)

These can’t be in a single TransactionalBatch (different containers/partitions). The Saga pattern handles this:

// Saga: provision a new device with compensating transactions
string deviceId = "sensor-5001";

try
{
    // Step 1: Create device
    await devicesContainer.CreateItemAsync(device, new PartitionKey(deviceId));

    try
    {
        // Step 2: Assign to fleet
        await fleetsContainer.PatchItemAsync<FleetItem>(
            "fleet-industrial",
            new PartitionKey("fleet-industrial"),
            new[] { PatchOperation.Add("/devices/-", deviceId) });

        try
        {
            // Step 3: Create monitoring config
            await configsContainer.CreateItemAsync(config, new PartitionKey(deviceId));

            Console.WriteLine("Device provisioned successfully.");
        }
        catch
        {
            // Compensate: remove from fleet
            await fleetsContainer.PatchItemAsync<FleetItem>(
                "fleet-industrial",
                new PartitionKey("fleet-industrial"),
                new[] { PatchOperation.Remove($"/devices/{fleetDeviceIndex}") });
            throw;
        }
    }
    catch
    {
        // Compensate: delete device
        await devicesContainer.DeleteItemAsync<DeviceItem>(deviceId, new PartitionKey(deviceId));
        throw;
    }
}
catch (Exception ex)
{
    Console.WriteLine($"Provisioning failed. All changes compensated. Error: {ex.Message}");
}

Saga trade-offs:

  • Not truly atomic β€” there’s a window where partial state is visible
  • Compensating transactions can also fail β€” you need retry logic and dead-letter queues
  • More complex β€” but it’s the only option for cross-partition/cross-container consistency

Comparing the three patterns

AspectTransactionalBatchStored procedureSaga
ScopeSingle partition, single containerSingle partition, single containerCross-partition, cross-container
Atomicityβœ… True ACID β€” all or nothingβœ… True ACID β€” all or nothing⚠️ Eventual β€” compensating transactions
LanguageC# / Java SDKJavaScript (server-side)C# / Java SDK (client-side orchestration)
Conditional logic❌ No β€” flat list of operationsβœ… Yes β€” read, validate, branchβœ… Yes β€” full client-side logic
Max operations100 operations, 2 MB5-second timeoutNo hard limit
ComplexityLowMediumHigh
Best forMulti-item CRUD in same partitionRead-check-write (e.g., inventory)Cross-partition workflows
πŸ’‘ Exam tip: when batch can't help

TransactionalBatch is flat β€” you can’t read an item, check a condition, and then decide what to write. If the question describes a read-then-decide-then-write pattern, the answer is a stored procedure (within one partition) or a Saga (across partitions). Batch is for known operations that don’t depend on reads.

πŸ’‘ Exam tip: saga is not ACID

The Saga pattern provides eventual consistency, not ACID atomicity. There’s always a window where partial state is visible. Compensating transactions may also fail, requiring idempotent operations and retry logic. The exam tests this distinction β€” if a question requires strict ACID across partitions, the answer is β€œnot possible with Cosmos DB” (redesign your data model to put the data in one partition).

🎬 Video walkthrough

🎬 Video coming soon

Transactions in Practice β€” DP-420 Module 11

Transactions in Practice β€” DP-420 Module 11

~12 min

Flashcards

Question

When should you use a stored procedure instead of TransactionalBatch?

Click or press Enter to reveal answer

Answer

When you need conditional logic β€” read a value, check a condition, then decide what to write. TransactionalBatch is a flat list with no branching. Stored procedures can read, validate, and branch within an ACID transaction.

Click to flip back

Question

Is the Saga pattern truly atomic?

Click or press Enter to reveal answer

Answer

No. Sagas provide eventual consistency through compensating transactions. There's a window where partial state is visible. Compensating transactions can also fail. Sagas are the only option for cross-partition consistency, but they're not ACID.

Click to flip back

Question

What is a compensating transaction in the Saga pattern?

Click or press Enter to reveal answer

Answer

An operation that undoes a previous step when a later step fails. For example, if step 3 fails, you run compensating transactions to undo steps 2 and 1. Compensating transactions must be idempotent (safe to retry).

Click to flip back

Knowledge check

Knowledge Check

Jake's GlobeCart needs to: (1) check product stock, (2) reserve inventory if available, (3) reject if out of stock. All data is in the same partition. Which approach is best?

Knowledge Check

Amara needs to write data to three different containers atomically. What's her best option?

Knowledge Check

During a Saga, step 2 of 3 succeeds but step 3 fails. The compensating transaction for step 2 also fails. What should happen?


Next up: Domain 2 β€” dive into indexing policies, consistency levels, and throughput optimisation to make your Cosmos DB data model perform at scale.

← Previous

Server-Side Programming

Next β†’

Global Replication and Failover

Guided

I learn, I simplify, I share.

A Guide to Cloud YouTube Feedback

© 2026 Sutheesh. All rights reserved.

Guided is an independent study resource and is not affiliated with, endorsed by, or officially connected to Microsoft. Microsoft, Azure, and related trademarks are property of Microsoft Corporation. Always verify information against Microsoft Learn.