I'm using MongoDB 4.0.8 with C# driver 2.8.1 and I'm trying to implement Transactions
in my project.
I copy-pasted the following code sample:
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(new TransactionOptions(
readConcern: ReadConcern.Snapshot,
writeConcern: WriteConcern.WMajority));
try
{
//Insert the sample data
await products.InsertOneAsync(session, TV);
await products.InsertOneAsync(session, Book);
await products.InsertOneAsync(session, DogBowl);
var filter = new FilterDefinitionBuilder<Product>().Empty;
var results = await products.Find(filter).ToListAsync();
//Increase all the prices by 10% for all products
var update = new UpdateDefinitionBuilder<Product>().Mul<Double>(r => r.Price, 1.1);
await products.UpdateManyAsync(session, 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;
}
But in the first Insert
command, I'm getting this error:
Command insert failed:
Transaction numbers are only allowed on a replica set member or mongos.
The Documentation says that:
Starting in version 4.0, MongoDB provides the ability to perform multi-document transactions against replica sets.
I don't have replicas in my project, I have only one database instance which is my primary one. If there a solution or a work-around I can use to implement Transactions
? I have methods that update more than one collection and I really think it could save me time to use it.
like the documentation says, transactions only work with replica sets. so you need to run your mongodb server as single node replica set. to achieve that, do the following steps...
step 1: stop the mongodb server.
step 2:
add the replication
setting to your mongod.cfg file. here's my own as an example
storage:
dbPath: C:\DATA
directoryPerDB: true
journal:
enabled: true
systemLog:
destination: file
logAppend: true
path: C:\DATA\log\mongod.log
net:
port: 27017
bindIp: 127.0.0.1
replication:
replSetName: MyRepSet
step 3: open up a mongodb shell and issue the following command to initiate the replica set.
rs.initiate()
step 4: restart mongod
on a side-note, if you'd like to write cleaner, more convenient transaction code like the following, check out my library MongoDB.Entities
using (var TN = new Transaction())
{
var author = new Author { Name = "one" };
TN.Save(author);
TN.Delete<Book>(book.ID);
TN.Commit();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With