Mongo4终于支持事务了,可适用于更多应用场景!
连接数据库:
private const string connUrl = "mongodb://127.0.0.1:27017";
/// <summary>
/// 指定的数据库
/// </summary>
private const string dbName = "TestDB";
protected static IMongoClient _client;
protected static IMongoDatabase _database;
private void OpenDb()
{
var url = new MongoUrl(connUrl);
var settings = MongoClientSettings.FromUrl(url);
settings.Credential = MongoCredential.CreateCredential(dbName, "admin", "123456");
//创建数据连接
_client = new MongoClient();
_database = _client.GetDatabase(dbName);
}
不启动事务的增删改查用法:
//查询
async void GetData()
{
try
{
IMongoCollection<T_User> collection = _database.GetCollection<T_User>("users");
var filter = new BsonDocument();
var data = await collection.Find(filter).ToListAsync();
if (data.Any())
{
foreach (var d in data)
{
ShowLog(d.ToString());
}
dataGridView1.DataSource = data;
}
}
catch (FormatException e)
{
//记录日志
}
}
//插入
var u = new T_User
{
name = tbName.Text,
password = tbPassword.Text
};
IMongoCollection<T_User> collection = _database.GetCollection<T_User>("users");
await collection.InsertOneAsync(u);
//修改
IMongoCollection<T_User> collection = _database.GetCollection<T_User>("users");
var filter = Builders<T_User>.Filter.Eq("_id", _selUser._id);
var update = Builders<T_User>.Update.Set("name", tbName.Text).Set("password", tbPassword.Text);
await collection.UpdateOneAsync(filter, update);
//删除
IMongoCollection<T_User> collection = _database.GetCollection<T_User>("users");
var filter = Builders<T_User>.Filter.Eq("_id", _selUser._id);
await collection.DeleteManyAsync(filter);
使用事务确保数据一致:
var s = _client.StartSession();
var database = s.Client.GetDatabase(dbName);
s.StartTransaction(new TransactionOptions(
readConcern: ReadConcern.Snapshot,
writeConcern: WriteConcern.WMajority));
try
{
IMongoCollection<T_User> collection = database.GetCollection<T_User>("users");
var filter = Builders<T_User>.Filter.Eq("_id", _selUser._id);
var update = Builders<T_User>.Update.Set("name", tbName.Text).Set("password", tbPassword.Text);
await collection.UpdateOneAsync(s, filter, update);
if (DateTime.Now.Year == 2018)
throw new Exception("不让提交成功");
s.CommitTransaction();
}
catch
{
var cancellationToken = new CancellationToken();
s.AbortTransaction(cancellationToken);
}
官方事务的用法:
public void UpdateEmployeeInfo(IMongoClient client, IClientSessionHandle session)
{
var employeesCollection = client.GetDatabase("hr").GetCollection<BsonDocument>("employees");
var eventsCollection = client.GetDatabase("reporting").GetCollection<BsonDocument>("events");
session.StartTransaction(new TransactionOptions(
readConcern: ReadConcern.Snapshot,
writeConcern: WriteConcern.WMajority));
try
{
employeesCollection.UpdateOne(
session,
Builders<BsonDocument>.Filter.Eq("employee", 3),
Builders<BsonDocument>.Update.Set("status", "Inactive"));
eventsCollection.InsertOne(
session,
new BsonDocument
{
{ "employee", 3 },
{ "status", new BsonDocument { { "new", "Inactive" }, { "old", "Active" } } }
});
}
catch (Exception exception)
{
Console.WriteLine($"Caught exception during transaction, aborting: {exception.Message}.");
session.AbortTransaction();
throw;
}
while (true)
{
try
{
session.CommitTransaction(); // uses write concern set at transaction start
Console.WriteLine("Transaction committed.");
break;
}
catch (MongoException exception)
{
// can retry commit
if (exception.HasErrorLabel("UnknownTransactionCommitResult"))
{
Console.WriteLine("UnknownTransactionCommitResult, retrying commit operation.");
continue;
}
else
{
Console.WriteLine("Error during commit.");
throw;
}
}
}
}
ps:mongodb安装为windows服务命令行:
mongod.exe --logpath D:\mongodb\logs\mongodb.log --logappend --dbpath D:\mongodb\data --directoryperdb --serviceName MongoDB --install
定义MongoDB的Validator约束Collection字段:
db.createCollection("Role", {
validator: { $jsonSchema: {
bsonType: "object",
required: ["RoleId","RoleName","Valid"],
properties: {
RoleId: {
bsonType:"int",
description:"required and must be a int" },
RoleName: {
bsonType: "string",
description: "required and must be a string" },
Valid: {
enum:["true","false"],
description: "can bu only true or false" },
remark: {
bsonType: "string",
description: ""}
}
}
}
})
//插入(int类型需要使用NumberInt函数进行转换):
db.Role.insert({RoleId:NumberInt(1),RoleName:"1",Valid:"true"})