可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Playing around with MongoDB and NoRM in .NET.
Thing that confused me - there are no transactions
(can't just tell MongoConnection.Begin/EndTransaction
or something like that).
I want to use Unit of work pattern and rollback changes in case something fails.
Is there still a clean way how to enrich my repository with ITransaction?
回答1:
MongoDB doesn't support complex multi-document transactions. If that is something you absolutely need it probably isn't a great fit for you.
In most cases, however, we've found that complex transactions aren't a requirement. All operations in MongoDB are atomic on a single document, and we support nice update modifiers, which make a lot of operations that would need a transaction easy to implement (and fast).
回答2:
That is true that MongoDB does't support transaction out of the box, but you can implement optimistic transactions on your own. They fit fine the unit of work. I wrote an java example and some explanation on a GitHub so you can easily repeat in C#.
回答3:
As of v4.0, MongoDB supports multi-document ACID transactions. Through snapshot isolation, transactions provide a globally consistent view of data, and enforce all-or-nothing execution to maintain data integrity. For more info, see https://www.mongodb.com/transactions
In 4.2, MongoDB will also support sharded transactions.
In this blog post, I also outline our journey to multi-document ACID transactions, in case if you are interested in the history and our reasoning.
回答4:
MongoDB 4.0 will add support for multi-document transactions.
https://www.mongodb.com/transactions
回答5:
Some notes for the record.
While MongoDB does not have transaction support, it supports atomicity on a single document:
MongoDB does have support for atomic operations within a single document. Given the possibilities provided by nested documents, this feature provides support for a large number of use-cases.
Also, the manual entry about "Isolate Sequence of Operations" might be interesting. E.g.:
however, you can isolate a single write operation that affects multiple documents using the isolation operator.
回答6:
You can use instead MongoDb TokuMX.
http://www.tokutek.com/products/tokumx-for-mongodb/
TokuMXTM is an open source, high-performance distribution of MongoDB that has dramatically improved performance and operational efficiency compared to basic MongoDB. TokuMX is a drop-in replacement for MongoDB, and offers 20X performance improvements, 90% reduction in database size, and support for ACID transactions with MVCC.
回答7:
FYI - this has now changed
using (var session = mongoDbContext.MongoDatabase.Client.StartSession())
{
var itemAuthRepo = (Repository<ItemAuthorization, ObjectId>)mongoDbContext.ItemAuthorizations;
var calendarRepo = (Repository<CalendarEvent, ObjectId>)mongoDbContext.Calendars;
if (itemAuthRepo != null && calendarRepo!=null)
{
session.StartTransaction();
try
{
itemAuthRepo.Collection.InsertOne(session, newItemAuthorization);
calendarRepo.Collection.InsertOne(session, cal);
session.CommitTransaction();
}
catch (Exception ex)
{
session.AbortTransaction();
throw;
}
}
else
{
throw new Exception("IRepository was not casted to Repository");
}
}
回答8:
Yes, there are multiple ways to apply Unit of Work pattern for MongoDB depending on the database version.
Until MongoDB 4.0, there was no support for multi-document ACID transactions. Then developers has used "two-phase commit protocol" (single database) and "three-phase commit protocol" (non-blocking on distributed databases) to create their own transaction layer which has provided data consistency but not all-or-nothing execution to maintain data integrity. So that way has taken down the performance.
MongoDB 4.0 has added support for multi-document ACID transactions.
Sources:
https://en.wikipedia.org/wiki/Two-phase_commit_protocol
https://en.wikipedia.org/wiki/Three-phase_commit_protocol
https://www.mongodb.com/transactions