diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs
index 671a676726..a8743c6e05 100644
--- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs
+++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs
@@ -1,4 +1,5 @@
using System;
+using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
@@ -7,6 +8,8 @@ using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using MongoDB.Driver;
+using MongoDB.Driver.Core.Misc;
+using MongoDB.Driver.Core.Servers;
using Volo.Abp.Data;
using Volo.Abp.MongoDB;
using Volo.Abp.MultiTenancy;
@@ -127,7 +130,7 @@ namespace Volo.Abp.Uow.MongoDB
var client = CreateMongoClient(mongoUrl);
var database = client.GetDatabase(databaseName);
- if (unitOfWork.Options.IsTransactional)
+ if (unitOfWork.Options.IsTransactional && IsSupportedTransactions(client))
{
return CreateDbContextWithTransaction(unitOfWork, mongoUrl, client, database);
}
@@ -147,7 +150,7 @@ namespace Volo.Abp.Uow.MongoDB
var client = CreateMongoClient(mongoUrl);
var database = client.GetDatabase(databaseName);
- if (unitOfWork.Options.IsTransactional)
+ if (unitOfWork.Options.IsTransactional && IsSupportedTransactions(client))
{
return await CreateDbContextWithTransactionAsync(
unitOfWork,
@@ -285,5 +288,55 @@ namespace Volo.Abp.Uow.MongoDB
{
return _cancellationTokenProvider.FallbackToProvider(preferredValue);
}
+
+ ///
+ /// https://github.com/mongodb/mongo-csharp-driver/blob/master/src/MongoDB.Driver.Core/Core/Bindings/CoreSession.cs#L495
+ ///
+ ///
+ ///
+ ///
+ protected virtual bool IsSupportedTransactions(MongoClient client)
+ {
+ try
+ {
+ var connectedDataBearingServers = client.Cluster.Description.Servers.Where(s => s.State == ServerState.Connected && s.IsDataBearing).ToList();
+
+ if (connectedDataBearingServers.Count == 0)
+ {
+ throw new NotSupportedException("StartTransaction cannot determine if transactions are supported because there are no connected servers.");
+ }
+
+ foreach (var connectedDataBearingServer in connectedDataBearingServers)
+ {
+ var serverType = connectedDataBearingServer.Type;
+
+ switch (serverType)
+ {
+ case ServerType.Standalone:
+ throw new NotSupportedException("Standalone servers do not support transactions.");
+ case ServerType.ShardRouter:
+ Feature.ShardedTransactions.ThrowIfNotSupported(connectedDataBearingServer.Version);
+ break;
+ case ServerType.LoadBalanced:
+ // do nothing, load balancing always supports transactions
+ break;
+ default:
+ Feature.Transactions.ThrowIfNotSupported(connectedDataBearingServer.Version);
+ break;
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ Logger.LogError("The current MongoDB database does not support transactions, " +
+ "All operations will be performed in non-transactions. " +
+ "This may cause errors, " +
+ "Please make your database support transactions.");
+ Logger.LogException(e);
+ return false;
+ }
+
+ return true;
+ }
}
}