Explore Developer Center's New Chatbot! MongoDB AI Chatbot can be accessed at the top of your navigation to answer all your MongoDB questions.

MongoDB Developer
C#
plus
Sign in to follow topics
MongoDB Developer Centerchevron-right
Developer Topicschevron-right
Languageschevron-right
C#chevron-right

Working With MongoDB Transactions With C# and the .NET Framework

Robert Walters3 min read • Published Jan 28, 2022 • Updated Sep 11, 2024
.NETMongoDBC#
Facebook Icontwitter iconlinkedin icon
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Update 10/2019: This article's code example has been updated to include the required handing of the session handle to database methods.
C# applications connected to a MongoDB database use the MongoDB .NET driver. To add the .NET driver to your Visual Studio Application, in the NuGet Package Manager, search for "MongoDB".
Make sure you choose the latest version (>=2.7) of the driver, and press Install.
Prior to MongoDB version 4.0, MongoDB was transactionally consistent at the document level. These existing atomic single-document operations provide the transaction semantics to meet the data integrity needs of the majority of applications. This is because the flexibility of the document model allows developers to easily embed related data for an entity as arrays and sub-documents within a single, rich document. That said, there are some cases where splitting the content into two or more collections would be appropriate, and for these cases, multi-document ACID transactions makes it easier than ever for developers to address the full spectrum of use cases with MongoDB. For a deeper discussion on MongoDB document model design, including how to represent one-to-many and many-to-many relationships, check out this article on data model design.
In the following code we will create a Product object and perform a MongoDB transaction that will insert some sample data into MongoDB then update the prices for all products by 10%.
1using MongoDB.Bson;
2using MongoDB.Bson.Serialization.Attributes;
3using MongoDB.Driver;
4using System;
5using System.Threading.Tasks;
6
7namespace MongoDBTransaction
8{
9 public static class Program
10 {
11 public class Product
12 {
13 [BsonId]
14 public ObjectId Id { get; set; }
15 [BsonElement("SKU")]
16 public int SKU { get; set; }
17 [BsonElement("Description")]
18 public string Description { get; set; }
19 [BsonElement("Price")]
20 public Double Price { get; set; }
21 }
22
23 // replace with your connection string if it is different
24 const string MongoDBConnectionString = "mongodb://localhost";
25
26 public static async Task Main(string[] args)
27 {
28 if (!await UpdateProductsAsync()) { Environment.Exit(1); }
29 Console.WriteLine("Finished updating the product collection");
30 Console.ReadKey();
31 }
32
33 private static async Task<bool> UpdateProductsAsync()
34 {
35 // Create client connection to our MongoDB database
36 var client = new MongoClient(MongoDBConnectionString);
37
38 // Create the collection object that represents the "products" collection
39 var database = client.GetDatabase("MongoDBStore");
40 var products = database.GetCollection<Product>("products");
41
42 // Clean up the collection if there is data in there
43 await database.DropCollectionAsync("products");
44
45 // collections can't be created inside a transaction so create it first
46 await database.CreateCollectionAsync("products");
47
48 // Create a session object that is used when leveraging transactions
49 using (var session = await client.StartSessionAsync())
50 {
51 // Begin transaction
52 session.StartTransaction();
53
54 try
55 {
56 // Create some sample data
57 var tv = new Product { Description = "Television",
58 SKU = 4001,
59 Price = 2000 };
60 var book = new Product { Description = "A funny book",
61 SKU = 43221,
62 Price = 19.99 };
63 var dogBowl = new Product { Description = "Bowl for Fido",
64 SKU = 123,
65 Price = 40.00 };
66
67 // Insert the sample data
68 await products.InsertOneAsync(session, tv);
69 await products.InsertOneAsync(session, book);
70 await products.InsertOneAsync(session, dogBowl);
71
72 var resultsBeforeUpdates = await products
73 .Find<Product>(session, Builders<Product>.Filter.Empty)
74 .ToListAsync();
75 Console.WriteLine("Original Prices:\n");
76 foreach (Product d in resultsBeforeUpdates)
77 {
78 Console.WriteLine(
79 String.Format("Product Name: {0}\tPrice: {1:0.00}",
80 d.Description, d.Price)
81 );
82 }
83
84 // Increase all the prices by 10% for all products
85 var update = new UpdateDefinitionBuilder<Product>()
86 .Mul<Double>(r => r.Price, 1.1);
87 await products.UpdateManyAsync(session,
88 Builders<Product>.Filter.Empty,
89 update); //,options);
90
91 // Made it here without error? Let's commit the transaction
92 await session.CommitTransactionAsync();
93 }
94 catch (Exception e)
95 {
96 Console.WriteLine("Error writing to MongoDB: " + e.Message);
97 await session.AbortTransactionAsync();
98 return false;
99 }
100
101 // Let's print the new results to the console
102 Console.WriteLine("\n\nNew Prices (10% increase):\n");
103 var resultsAfterCommit = await products
104 .Find<Product>(session, Builders<Product>.Filter.Empty)
105 .ToListAsync();
106 foreach (Product d in resultsAfterCommit)
107 {
108 Console.WriteLine(
109 String.Format("Product Name: {0}\tPrice: {1:0.00}",
110 d.Description, d.Price)
111 );
112 }
113
114 return true;
115 }
116 }
117 }
118}
Source Code available on Gist. Successful execution yields the following:

Key points:

  • You don't have to match class properties to JSON objects - just define a class object and insert it directly into the database. There is no need for an Object Relational Mapper (ORM) layer.
  • MongoDB transactions use snapshot isolation meaning only the client involved in the transactional session sees any changes until such time as the transaction is committed.
  • The MongoDB .NET Driver makes it easy to leverage transactions and leverage LINQ based syntax for queries.
Additional information about using C# and the .NET driver can be found in the C# and .NET MongoDB Driver documentation.

Facebook Icontwitter iconlinkedin icon
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Related
Tutorial

Handling Complex Aggregation Pipelines With C#


Nov 15, 2024 | 5 min read
Tutorial

MongoDB Atlas Search with .NET Blazor for Full-Text Search


Feb 01, 2024 | 6 min read
Tutorial

MongoDB C# Aggregation Pipeline Basics


Oct 11, 2024 | 5 min read
Tutorial

Building a Crypto News Website in C# Using the Microsoft Azure App Service and MongoDB Atlas


Jun 13, 2023 | 9 min read
Table of Contents
  • Key points: