Azure Cosmos DB is a multi-model, globally distributed NoSQL database designed for fast and predictable performance, high availability, elastic scalability, and ease of development. It is ideal for handling large amounts of distributed data and multi-tenant applications. However, in Azure Cosmos DB, there is no native support for handling multiple documents transactionally.
By default, operations on documents in Azure Cosmos DB are not transactional. That means if multiple documents are updated in a single operation, the changes are not committed atomically. This can be problematic, especially in cases where consistency across multiple documents is necessary.
This issue can be resolved by using JavaScript-stored procedures in Azure Cosmos DB. A stored procedure provides an ACID transaction that encompasses multiple operations against documents. Changes to documents in a stored procedure are applied or rolled back together, making it the perfect solution for handling multiple documents transactionally.
Let us explore the process for creating stored procedures to work with multiple documents transactionally in Azure Cosmos DB:
-
Creating a Stored Procedure
-
Working with Multiple Documents
Stored procedures are written in JavaScript and execute in the context of a partition key value. It is crucial to write optimal, efficient stored procedures, as they are subject to the same timeouts as other operations.
Here’s a basic example of a stored procedure:
function createDocument(documentToCreate) {
var context = getContext();
var container = context.getCollection();
var accepted = container.createDocument(container.getSelfLink(),
documentToCreate,
function (err, documentCreated) {
if (err) throw new Error('Error' + err.message);
context.getResponse().setBody(documentCreated);
});
if (!accepted) throw new Error('The query was not accepted by the server.');
}
To illustrate the concept better, let’s consider a scenario where ‘Order’ and ‘Inventory’ are two separate documents. For a successful transaction, both these documents need to be updated together. If the update on either fails, both should rollback to their previous states.
For this, we can create a stored procedure as follows:
function updateMultipleDocuments(orderId, orderStatus, inventoryId, decrementQuantity) {
var context = getContext();
var collectionLink = context.getCollection().getSelfLink();
var collection = context.getCollection();
// Query documents for the order
var orderQuery = 'SELECT * FROM root r WHERE r.id = "' + orderId + '"';
var orderAccepted = collection.queryDocuments(collectionLink, orderQuery, {},
function (err, orders, responseOptions) {
if (err) throw err;
// Should have found exactly 1 order document
if (!orders || orders.length != 1) throw "Could not find the order document with id: " + orderId;
var orderDocument = orders[0];
// Update the order status
orderDocument.status = orderStatus;
var orderReplaceAccepted = collection.replaceDocument(orderDocument._self, orderDocument,
function (err, orderReplaced) {
if (err) throw err;
// Now let's search the inventory document
var inventoryQuery = 'SELECT * FROM root r WHERE r.id = "' + inventoryId + '"';
var inventoryAccepted = collection.queryDocuments(collectionLink, inventoryQuery, {},
function (err, inventories, responseOptions) {
if (err) throw err;
// Found exactly 1 inventory document
if (!inventories || inventories.length != 1) throw "Could not find the inventory document with id: " + inventoryId;
var inventoryDocument = inventories[0];
//Decrement the inventory count
inventoryDocument.quantity = inventoryDocument.quantity - decrementQuantity;
var inventoryReplaceAccepted = collection.replaceDocument(inventoryDocument._self, inventoryDocument,
function (err, inventoryReplaced) {
if (err) throw err;
var response = context.getResponse();
response.setBody("Success in updating the Order and Inventory documents");
});
});
});
});
if (!orderAccepted) throw new Error('The stored procedure query for orders was not accepted by the server.');
}
This stored procedure ensures both updates (i.e., updating the order status and decrementing the inventory quantity by some amount) commit together as a part of a single transaction. If any operation fails, no changes are committed to either document, ensuring data integrity.
To summarize, stored procedures in Azure Cosmos DB are a powerful tool that enables a transactional way of working with multiple documents. As you prepare for the DP-420 certification exam, be sure to practice creating and managing stored procedures in Azure Cosmos DB to bolster your skills in designing and implementing native applications for it.
Practice Test
True or False: Transactions in Azure Cosmos DB can span across multiple logical partitions.
- True
- False
Answer: False.
Explanation: In Azure Cosmos DB, a single transaction cannot span across multiple logical partitions.
In Azure Cosmos DB, you can utilize stored procedures for running a sequence of operations within a single transaction. Is this statement True or False?
- True
- False
Answer: True.
Explanation: This statement is accurate because stored procedures provide atomic transaction capability and can execute multiple operations.
When should one use stored procedures in Azure Cosmos DB?
- a) When you want to read data
- b) When you want to update data in multiple documents
- c) When you need to analyze data
Answer: b) When you want to update data in multiple documents
Explanation: Stored procedures in Azure Cosmos DB are best used for updating multiple documents within a single atomic transaction.
True or False: Stored procedures in Azure Cosmos DB can operate at either per-partition or cross-partition granularity level.
- True
- False
Answer: False.
Explanation: Stored procedures in Azure Cosmos DB operate at a per-partition granularity level.
What does it mean that stored procedures in Azure Cosmos DB are run within atomic transactions?
- a) They can be run in parallel
- b) They can be only run sequentially
- c) Operations are all done or undone together
Answer: c) Operations are all done or undone together
Explanation: “Atomic” in the context of transactions implies that operations are all completed successfully, or none are done.
In Azure Cosmos DB, can a stored procedure run across wallets or containers?
- Yes
- No
Answer: No.
Explanation: Stored procedures operate on a specified logical partition key within a particular container.
Is it possible to design stored procedures to conduct business logic across multiple documents transactionally in Azure Cosmos DB?
- Yes
- No
Answer: Yes.
Explanation: The stored procedures in Azure Cosmos DB can be designed to conduct business logic transactionally across multiple documents.
Does designing stored procedures to work with multiple documents transactionally guarantee the atomicity of transactions?
- Yes
- No
Answer: Yes.
Explanation: Stored procedures in Azure Cosmos DB provide atomic transactions, ensuring that all operations will run successfully, or none will apply.
True or False: Stored procedures can be written in any programming language.
- True
- False
Answer: False.
Explanation: Stored procedures in Azure Cosmos DB have to be written in JavaScript.
Who is responsible for retrying a transaction if a stored procedure fails in the Azure Cosmos DB?
- a) Azure Cosmos DB
- b) Developer
Answer: b) Developer
Explanation: It is the developer’s responsibility to retry the transaction if a stored procedure execution is throttled or fails.
True or False: One of the benefits of Azure Cosmos DB stored procedures is that they allow operations that span multiple logical partitions.
- True
- False
Answer: False.
Explanation: Stored procedures are scoped to a partition key and operate on a single partition.
True or False: If a new document is added to Cosmos DB while a stored procedure is running, the stored procedure will automatically include the new document.
- True
- False
Answer: False.
Explanation: The consistency model applies to reads, including those within stored procedures.
True or False: The stored procedures in Azure Cosmos DB provide more efficient CRUD operations than using SQL API requests.
- True
- False
Answer: True.
Explanation: Since stored procedures are co-located with data, they provide very efficient CRUD operations.
Which of the following statements are correct about transactions in Azure Cosmos DB stored procedures?
- a) They are automatically committed
- b) They can be manually rolled back
- c) They can be manually committed
- d) They are automatically rolled back on an error
Answer: a) They are automatically committed, d) They are automatically rolled back on an error
Explanation: Azure Cosmos DB transactions in stored procedures are automatically committed if no errors occur during the execution. If an error occurs, the transaction automatically rolls back.
Interview Questions
What is a stored procedure in the context of Microsoft Azure Cosmos DB?
A stored procedure is a programmable routine that is written in JavaScript and stored in the database. It performs transactions on an Azure Cosmos container.
What are the benefits of using stored procedures in Azure Cosmos DB?
Stored procedures allow you to perform operations within the Azure Cosmos DB service directly on the client-side. They are beneficial for reducing network round trips, implementing business logic, improving performance, and conducting transactional operations.
Can stored procedures work with multiple documents in a single transaction in Azure Cosmos DB?
Yes, stored procedures can perform operations on multiple items (documents) in a single atomic transaction within a logical partition.
How can I create a stored procedure in Azure Cosmos DB?
You can create a stored procedure using the Azure portal, the SDKs, or the REST API. The procedure should be written in JavaScript.
Are there any limitations when using stored procedures with Azure Cosmos DB?
Yes, there are some limitations. Stored procedures run in a single partition, they cannot operate across multiple partitions or containers. Furthermore, they are bound by the maximum execution time of 5 seconds and they consume request units (RUs) during execution.
What is the ACID property in the context of Azure Cosmos DB stored procedures?
ACID stands for Atomicity, Consistency, Isolation, Durability. It refers to the set of properties that guarantee reliable processing of database operations. Azure Cosmos DB ensures ACID properties for all its transactional operations including stored procedures.
What is a transaction in the context of Azure Cosmos DB stored procedures?
A transaction refers to an indivisible unit of work. In Azure Cosmos DB, a transaction is scoped to a single partition key within a container where multiple operations can be performed atomically.
What happens when an error occurs within a stored procedure in Azure Cosmos DB?
In case an error occurs in a stored procedure, all modifications made within the same execution are rolled back atomically, ensuring consistency.
Can a stored procedure in Azure Cosmos DB be paused and then resumed?
No, stored procedures run to completion and cannot be paused and resumed. If a stored procedure is paused, it is actually terminated.
What is the purpose of the context object in Azure Cosmos DB stored procedures?
The context object represents the environment in which the stored procedure is being run. It allows access to operations such as reading, creating, deleting, or replacing items, and can operate on the response sent back to the client.
Can stored procedures in Azure Cosmos DB run on secondary read regions?
No, stored procedures can only be executed in the primary write region. They cannot run on secondary read regions.
How can you execute a stored procedure in Azure Cosmos DB?
Stored procedures can be executed using Azure portal, SDK, or REST API by specifying the script and the parameters it takes.
What happens if a stored procedure execution exceeds the allotted quota of RUs (Request Units)?
If the execution exceeds the allotted quota of RUs, Azure Cosmos DB would terminate the stored procedure. The operation will have to be retried with a higher provisioned throughput or after the database’s consumption rate slows down.
Does Azure Cosmos DB support asynchronous execution of stored procedures?
No, execution of stored procedures in Azure Cosmos DB is always synchronous and run to completion.
Can I create and execute stored procedures using Azure Cosmos DB’s SQL API?
Yes, Azure Cosmos DB’s SQL API supports creating and executing JavaScript-based stored procedures.