Configure consistency models in the portal and the Azure Cosmos DB for NoSQL SDK

The default consistency level for new Azure Cosmos DB for NoSQL accounts is session consistency. This default setting can be modified for all future requests. At an individual request level, you can go a step further and relax the consistency level for that specific request.

In this lab, we will configure the default consistency level for an Azure Cosmos DB for NoSQL account and then configure a consistency level for an individual operation using the SDK.

Prepare your development environment

If you have not already cloned the lab code repository for DP-420 to the environment where you’re working on this lab, follow these steps to do so. Otherwise, open the previously cloned folder in Visual Studio Code.

  1. Start Visual Studio Code.

    πŸ“ If you are not already familiar with the Visual Studio Code interface, review the Getting Started documentation

  2. Open the command palette and run Git: Clone to clone the https://github.com/microsoftlearning/dp-420-cosmos-db-dev GitHub repository in a local folder of your choice.

    πŸ’‘ You can use the CTRL+SHIFT+P keyboard shortcut to open the command palette.

  3. Once the repository has been cloned, open the local folder you selected in Visual Studio Code.

Create an Azure Cosmos DB for NoSQL account

Azure Cosmos DB is a cloud-based NoSQL database service that supports multiple APIs. When provisioning an Azure Cosmos DB account for the first time, you will select which of the APIs you want the account to support (for example, Mongo API or NoSQL API). Once the Azure Cosmos DB for NoSQL account is done provisioning, you can retrieve the endpoint and key and use them to connect to the Azure Cosmos DB for NoSQL account using the Azure SDK for .NET or any other SDK of your choice.

  1. In a new web browser window or tab, navigate to the Azure portal (portal.azure.com).

  2. Sign into the portal using the Microsoft credentials associated with your subscription.

  3. Select + Create a resource, search for Cosmos DB, and then create a new Azure Cosmos DB for NoSQL account resource with the following settings, leaving all remaining settings to their default values:

    Setting Value
    Subscription Your existing Azure subscription
    Resource group Select an existing or create a new resource group
    Account Name Enter a globally unique name
    Location Choose any available region
    Capacity mode Provisioned throughput
    Global Distribution | Geo-Redundancy Enable
    Apply Free Tier Discount Do Not Apply

    πŸ“ Your lab environments may have restrictions preventing you from creating a new resource group. If that is the case, use the existing pre-created resource group.

  4. Wait for the deployment task to complete before continuing with this task.

  5. Go to the newly created Azure Cosmos DB account resource and navigate to the Replicate data globally pane.

  6. In the Replicate data globally pane, add two extra read regions to the account and then Save your changes.

    πŸ“ In a couple of steps, you will be asked to change the consistency level to Strong, but do note that strong consistency for accounts with regions spanning more than 5000 miles (8000 kilometers) is blocked by default due to high write latency. Make sure you pick regions that are closer together. In a production environment, to enable this capability, please contact support.

  7. Wait for the replication task to complete before continuing with this task.

    πŸ“ This operation can take approximately 5-10 minutes.and navigate to the Default consistency pane.

  8. In the resource blade, navigate to the Default consistency pane.

  9. In the Default consistency pane, select the Strong option and then Save your changes.

  10. Wait for the change to the default consistency level to persist before continuing with this task.

  11. In the resource blade, navigate to the Data Explorer pane.

  12. In the Data Explorer pane, select New Container.

  13. In the New Container popup, enter the following values for each setting, and then select OK:

    Setting Value
    Database id Create new | cosmicworks
    Share throughput across containers Do not select
    Container id products
    Partition key /categoryId
    Container throughput Manual | 400
  14. Back in the Data Explorer pane, expand the cosmicworks database node and then observe the products container node within the hierarchy.

  15. In the Data Explorer pane, expand the cosmicworks database node, expand the products container node, and then select Items.

  16. Still in the Data Explorer pane, select New Item from the command bar. In the editor, replace the placeholder JSON item with the following content:

     {
       "id": "7d9273d9-5d91-404c-bb2d-126abb6e4833",
       "categoryId": "78d204a2-7d64-4f4a-ac29-9bfc437ae959",
       "categoryName": "Components, Pedals",
       "sku": "PD-R563",
       "name": "ML Road Pedal",
       "price": 62.09
     }
    
  17. Select Save from the command bar to add the JSON item:

  18. In the Items tab, observe the new item in the Items pane.

  19. In the resource blade, navigate to the Keys pane.

  20. This pane contains the connection details and credentials necessary to connect to the account from the SDK. Specifically:

    1. Notice the URI field. You will use this endpoint value later in this exercise.

    2. Notice the PRIMARY KEY field. You will use this key value later in this exercise.

  21. Return to Visual Studio Code.

Connect to the Azure Cosmos DB for NoSQL account from the SDK

Using the credentials from the newly created account, you will connect with the SDK classes and create a new database and container instance. Then, you will use the Data Explorer to validate that the instances exist in the Azure portal.

  1. In the Explorer pane, browse to the 21-sdk-consistency-model folder.

  2. Open the context menu for the 21-sdk-consistency-model folder and then select Open in Integrated Terminal to open a new terminal instance.

    πŸ“ This command will open the terminal with the starting directory already set to the 21-sdk-consistency-model folder.

  3. Build the project using the dotnet build command:

     dotnet build
    

    πŸ“ You may see a compiler warning that the endpoint and key variables are current unused. You can safely ignore this warning as you will use these variable in this task.

  4. Close the integrated terminal.

  5. Open the product.cs code file.

  6. Observe the Product record and its corresponding properties. Specifically, this lab will use the id, name, and categoryId properties.

  7. Back in the Explorer pane of Visual Studio Code, open the script.cs code file.

    πŸ“ The [Microsoft.Azure.Cosmos][nuget.org/packages/microsoft.azure.cosmos/3.22.1] library has already been pre-imported from NuGet.

  8. Locate the string variable named endpoint. Set its value to the endpoint of the Azure Cosmos DB account you created earlier.

     string endpoint = "<cosmos-endpoint>";
    

    πŸ“ For example, if your endpoint is: httpsΒ­://dp420.documents.azure.com:443/, then the C# statement would be: string endpoint = β€œhttpsΒ­://dp420.documents.azure.com:443/”;.

  9. Locate the string variable named key. Set its value to the key of the Azure Cosmos DB account you created earlier.

     string key = "<cosmos-key>";
    

    πŸ“ For example, if your key is: fDR2ci9QgkdkvERTQ==, then the C# statement would be: string key = β€œfDR2ci9QgkdkvERTQ==”;.

  10. Save the script.cs code file.

Configure consistency level for a point operation

The ItemRequestOptions class contains configuration properties on a per-request basis. Using this class, you will relax the consistency level from the current default of strong to eventual consistency.

  1. Create a string variable named id with a value of 7d9273d9-5d91-404c-bb2d-126abb6e4833:

     string id = "7d9273d9-5d91-404c-bb2d-126abb6e4833";
    
  2. Create a string variable named categoryId with a value of 78d204a2-7d64-4f4a-ac29-9bfc437ae959:

     string categoryId = "78d204a2-7d64-4f4a-ac29-9bfc437ae959";
    
  3. Create a variable of type PartitionKey named partitionKey passing in the categoryId variable as a constructor parameter:

     PartitionKey partitionKey = new (categoryId);
    
  4. Asynchronously invoke the generic ReadItemAsync<> method of the container variable passing in the id and partitionkey variables as method parameters, using Product as the generic type, and storing the result in a variable named response of type ItemResponse<Product>:

     ItemResponse<Product> response = await container.ReadItemAsync<Product>(id, partitionKey);
    
  5. Invoke the static Console.WriteLine method to print the request charge using a formatted output string:

     Console.WriteLine($"STRONG Request Charge:\t{response.RequestCharge:0.00} RUs");
    
  6. Once you are done, your code file should now include:

     using Microsoft.Azure.Cosmos;
    
     string endpoint = "<cosmos-endpoint>";
     string key = "<cosmos-key>";
    
     CosmosClient client = new CosmosClient(endpoint, key);
        
     Container container = client.GetContainer("cosmicworks", "products");
        
     string id = "7d9273d9-5d91-404c-bb2d-126abb6e4833";
        
     string categoryId = "78d204a2-7d64-4f4a-ac29-9bfc437ae959";
     PartitionKey partitionKey = new (categoryId);
        
     ItemResponse<Product> response = await container.ReadItemAsync<Product>(id, partitionKey);
        
     Console.WriteLine($"STRONG Request Charge:\t{response.RequestCharge:0.00} RUs");
    
  7. Save the script.cs code file.

  8. In Visual Studio Code, open the context menu for the 21-sdk-consistency-model folder and then select Open in Integrated Terminal to open a new terminal instance.

  9. Build and run the project using the dotnet run command:

     dotnet run
    
  10. Observe the output from the terminal. The request charge (in RUs) should be printed to the console.

    πŸ“ The current request charge should be 2 RUs. This is due to the strong consistency requiring a read from at least two replicas to ensure that it has the latest write.

  11. Close the integrated terminal.

  12. Return to the editor tab for the script.cs code file.

  13. Delete the following lines of code:

     ItemResponse<Product> response = await container.ReadItemAsync<Product>(id, partitionKey);
        
     Console.WriteLine($"Request Charge:\t{response.RequestCharge:0.00} RUs");
    
  14. Create a new variable named options of type ItemRequestOptions setting the ConsistencyLevel property to the ConsistencyLevel.Eventual enum value:

     ItemRequestOptions options = new()
     { 
         ConsistencyLevel = ConsistencyLevel.Eventual 
     };
    
  15. Asynchronously invoke the generic ReadItemAsync<> method of the container variable passing in the id, partitionKey, and options variables as method parameters, using Product as the generic type, and storing the result in a variable named response of type ItemResponse<Product>:

     ItemResponse<Product> response = await container.ReadItemAsync<Product>(id, partitionKey, requestOptions: options);
    
  16. Invoke the static Console.WriteLine method to print the request charge using a formatted output string:

     Console.WriteLine($"EVENTUAL Request Charge:\t{response.RequestCharge:0.00} RUs");
    
  17. Once you are done, your code file should now include:

     using Microsoft.Azure.Cosmos;
    
     string endpoint = "<cosmos-endpoint>";
     string key = "<cosmos-key>";
    
     CosmosClient client = new CosmosClient(endpoint, key);
        
     Container container = client.GetContainer("cosmicworks", "products");
        
     string id = "7d9273d9-5d91-404c-bb2d-126abb6e4833";
        
     string categoryId = "78d204a2-7d64-4f4a-ac29-9bfc437ae959";
     PartitionKey partitionKey = new (categoryId);
    
     ItemRequestOptions options = new()
     { 
         ConsistencyLevel = ConsistencyLevel.Eventual 
     };
        
     ItemResponse<Product> response = await container.ReadItemAsync<Product>(id, partitionKey, requestOptions: options);
        
     Console.WriteLine($"EVENTUAL Request Charge:\t{response.RequestCharge:0.00} RUs");
    
  18. Save the script.cs code file.

  19. In Visual Studio Code, open the context menu for the 21-sdk-consistency-model folder and then select Open in Integrated Terminal to open a new terminal instance.

  20. Build and run the project using the dotnet run command:

     dotnet run
    
  21. Observe the output from the terminal. The request charge (in RUs) should be printed to the console.

    πŸ“ The current request charge should be 1 RUs. This is due to the eventual consistency only requiring a read from a single replica.

  22. Close the integrated terminal.

  23. Close Visual Studio Code.