Concepts
Designing and implementing native applications using Microsoft Azure Cosmos DB allows developers to build highly scalable and globally distributed solutions. One important aspect of working with Cosmos DB is designing and implementing stored procedures to work with multiple documents transactionally. In this article, we will explore the best practices and techniques for achieving this.
Creating Collections
Before we dive into stored procedures, let’s create the collections in our Cosmos DB account. We can do this using the Azure portal or programmatically using the Cosmos DB SDKs.
Here’s an example of creating the orders and inventory collections:
await client.createContainer({
    id: "orders",
    partitionKey: { paths: ["/customerId"] }
});
await client.createContainer({
    id: "inventory",
    partitionKey: { paths: ["/productId"] }
});
Defining the Stored Procedure
Next, let’s define our stored procedure to process an order. The stored procedure will reduce the inventory count and create an order document in a single transaction.
// Define the stored procedure
function processOrder(order) {
    var collection = getContext().getCollection();
    var response = getContext().getResponse();
    // Validate input
    if (!order.customerId || !order.productId || !order.quantity) {
        response.setBody("Invalid input");
        return;
    }
    // Retrieve the inventory document
    var inventoryLink = collection.getAltLink() + "/docs/" + order.productId;
    collection.readDocument(inventoryLink, function (err, inventory) {
        if (err) {
            response.setBody("Error reading inventory document: " + err.message);
        } else {
            // Check if there is enough stock
            if (inventory.quantity >= order.quantity) {
                // Update the inventory count
                inventory.quantity -= order.quantity;
                collection.replaceDocument(inventoryLink, inventory, function (err, updatedInventory) {
                   if (err) {
                     response.setBody("Error updating inventory document: " + err.message);
                   } else {
                    // Create the order document
                    order.id = "order-" + Date.now();
                    collection.createDocument(collection.getSelfLink(), order, function (err, createdOrder) {
                      if (err) {
                       response.setBody("Error creating order document: " + err.message);
                      } else {
                       response.setBody("Order processed successfully");
                      }
                    });
            }
            } else {
                response.setBody("Insufficient stock");
            }
        }
    });
}
Invoking the Stored Procedure
Finally, let’s see how we can invoke the stored procedure from our application code. The following code snippet demonstrates how to execute the stored procedure using the JavaScript SDK:
var order = {
    customerId: "customer-123",
    productId: "product-456",
    quantity: 2
};
var requestOptions = {
    partitionKey: order.customerId
};
client.scripts.storedProcedure("processOrder").execute(requestOptions, order, function (err, result) {
    if (err) {
        console.log("Error processing order: " + err.message);
    } else {
        console.log("Order processed successfully");
    }
});
In the code above, we first define an order object with the required properties. We also specify the partition key for the order, which in our case is the customer ID. We then execute the stored procedure using the `execute` method of the `StoredProcedure` object.
By using stored procedures and executing them in a transactional manner, we can ensure the consistency of our data. If any operation within the stored procedure fails, the entire transaction will be rolled back, maintaining the integrity of our data.
In conclusion, designing and implementing stored procedures to work with multiple documents transactionally in Azure Cosmos DB is a powerful feature that allows us to create highly scalable and reliable native applications. By following the best practices and techniques outlined in this article, you can ensure the consistency and integrity of your data in Cosmos DB.
Answer the Questions in Comment Section
True/False: In Microsoft Azure Cosmos DB, stored procedures can be used to work with multiple documents transactionally.
Correct Answer: True
Which of the following statements about stored procedures in Azure Cosmos DB is correct?
a) Stored procedures execute on the client side.
b) Stored procedures are written in JavaScript.
c) Stored procedures cannot work with multiple documents transactionally.
d) Stored procedures can only be used for read operations.
Correct Answer: b) Stored procedures are written in JavaScript.
True/False: Stored procedures in Azure Cosmos DB are executed and executed atomically on a single partition key.
Correct Answer: True
Which of the following statements is true about transactions in Azure Cosmos DB?
a) Transactions can only involve a single document.
b) Transactions cannot be performed using stored procedures.
c) Transactions can be used to work with multiple documents transactionally.
d) Transactions are only available in the SQL API.
Correct Answer: c) Transactions can be used to work with multiple documents transactionally.
True/False: Stored procedures in Azure Cosmos DB can be used to enforce business logic and perform complex data manipulation tasks.
Correct Answer: True
In Azure Cosmos DB, which API supports the execution of stored procedures?
a) Gremlin API.
b) Table API.
c) MongoDB API.
d) SQL API.
Correct Answer: d) SQL API
Which of the following statements about stored procedures in Azure Cosmos DB is NOT true?
a) Stored procedures are stored in the database.
b) Stored procedures can be executed using a SQL query.
c) Stored procedures can access system functions and stored procedures.
d) Stored procedures cannot be parameterized.
Correct Answer: d) Stored procedures cannot be parameterized.
True/False: Stored procedures in Azure Cosmos DB can be used to perform batch operations.
Correct Answer: True
Which of the following is NOT a benefit of using stored procedures in Azure Cosmos DB?
a) Improved performance due to reduced network round trips.
b) Enhanced security by preventing unauthorized access to data.
c) Simplified application development by offloading complex operations to the database.
d) Reduced scalability as stored procedures can only be executed on a single partition.
Correct Answer: d) Reduced scalability as stored procedures can only be executed on a single partition.
True/False: Stored procedures in Azure Cosmos DB can be versioned and updated without having to modify the client code.
Correct Answer: True
Great insights on designing stored procedures for multi-document transactions in Cosmos DB! Thank you!
Can anyone explain the pros and cons of using stored procedures vs. change feed for transaction management?
How do you handle error handling in stored procedures for Cosmos DB?
Thanks for the blog post, it was really helpful!
I appreciate the post, but do you have any examples of stored procedures for Cosmos DB?
Helpful post. Clarified a lot of my doubts.
Could someone explain how throughput is affected by using stored procedures for batch processing?
Clear and concise! Thanks a lot!