Skip to content

Instantly share code, notes, and snippets.

@RWaltersMA
Created October 16, 2018 17:53
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save RWaltersMA/ea1bea3d6ffba6e82be235ed3d655eec to your computer and use it in GitHub Desktop.
Save RWaltersMA/ea1bea3d6ffba6e82be235ed3d655eec to your computer and use it in GitHub Desktop.
Example C# code showing MongoDB Transactions using the MongoDB .NET Driver (2.7+)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Bson.Serialization.Attributes;
namespace MongoDBTransaction
{
class Program
{
public class Product
{
[BsonId]
public ObjectId Id { get; set; }
[BsonElement("SKU")]
public int SKU { get; set; }
[BsonElement("Description")]
public string Description { get; set; }
[BsonElement("Price")]
public Double Price { get; set; }
}
const string MongoDBConnectionString = "mongodb+srv://<<MONGODB CONNECTION STRING>>";
static async Task Main(string[] args)
{
if (!await UpdateProducts()) { Environment.Exit(0); }
Console.WriteLine("Finished updating the product collection");
Console.ReadKey();
}
static async Task<bool> UpdateProducts()
{
//Create client connection to our MongoDB database
var client = new MongoClient(MongoDBConnectionString);
//Create a session object that is used when leveraging transactions
var session = client.StartSession();
//Create the collection object that represents the "products" collection
var products = session.Client.GetDatabase("MongoDBStore").GetCollection<Product>("products");
//Clean up the collection if there is data in there
products.Database.DropCollection("products");
//Create some sample data
var TV = new Product { Description = "Television", SKU = 4001, Price = 2000 };
var Book = new Product { Description = "A funny book", SKU = 43221, Price = 19.99 };
var DogBowl = new Product { Description = "Bowl for Fido", SKU = 123, Price = 40.00 };
//Begin transaction
session.StartTransaction();
try
{
//Insert the sample data
await products.InsertOneAsync(TV);
await products.InsertOneAsync(Book);
await products.InsertOneAsync(DogBowl);
var filter = new FilterDefinitionBuilder<Product>().Empty;
var results = await products.Find<Product>(filter).ToListAsync();
Console.WriteLine("Original Prices:\n");
foreach (Product d in results)
{
Console.WriteLine(String.Format("Product Name: {0}\tPrice: {1:0.00}", d.Description, d.Price));
}
//Increase all the prices by 10% for all products
var update = new UpdateDefinitionBuilder<Product>().Mul<Double>(r=>r.Price,1.1);
await products.UpdateManyAsync(filter, update); //,options);
//Made it here without error? Let's commit the transaction
session.CommitTransaction();
//Let's print the new results to the console
Console.WriteLine("Original Prices:\n");
results = await products.Find<Product>(filter).ToListAsync();
foreach (Product d in results)
{
Console.WriteLine(String.Format("Product Name: {0}\tPrice: {1:0.00}", d.Description, d.Price));
}
}
catch (Exception e)
{
Console.WriteLine("Error writing to MongoDB: " + e.Message);
session.AbortTransaction();
}
return true;
}
}
}
@par4dise
Copy link

Thanks for this piece of code but... your gist might be obsolete?
You should call InsertOneAsync with session as 1st parameter, otherwise the operations are run outside the transaction. To observe this behavior: replace CommitTransaction by AbortTransaction... all written data is still persisted.
Documentation says:

When a transaction aborts, all data changes made by the writes in the transaction are discarded without ever becoming visible and the transaction ends.

https://docs.mongodb.com/manual/reference/command/abortTransaction/

@AtakanPehlivanoglu
Copy link

Thanks for this piece of code but... your gist might be obsolete?
You should call InsertOneAsync with session as 1st parameter, otherwise the operations are run outside the transaction. To observe this behavior: replace CommitTransaction by AbortTransaction... all written data is still persisted.
Documentation says:

When a transaction aborts, all data changes made by the writes in the transaction are discarded without ever becoming visible and the transaction ends.

https://docs.mongodb.com/manual/reference/command/abortTransaction/

Man, thanks for the help!
I also forgot to put current client session in to CRUD operation then my problem has been solved as well

@okellodaniel
Copy link

Thanks for sharing mate

@prosa21
Copy link

prosa21 commented Oct 23, 2023

Thank you for this code.
Didn't you forget to dispose of the session?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment