diff --git a/src/Session.Tests/MongoSessionProviderTests.cs b/src/Session.Tests/MongoSessionProviderTests.cs index 4a0aa0d..b549437 100644 --- a/src/Session.Tests/MongoSessionProviderTests.cs +++ b/src/Session.Tests/MongoSessionProviderTests.cs @@ -65,6 +65,26 @@ public async Task StartSessionAsync_ShouldStartSession() clientSessionHandle.IsInTransaction.Should().BeFalse(); } + [Fact] + public async Task StartTransaction_ShouldBeginTransaction() + { + // Arrange + ISessionProvider sessionProvider = _serviceProvider + .GetRequiredService>(); + ISession session = await sessionProvider + .StartSessionAsync(CancellationToken.None); + + // Act + ITransactionSession transactionSession = session + .StartTransaction(CancellationToken.None); + + // Assert + transactionSession.Should().NotBeNull(); + IClientSessionHandle clientSessionHandle = transactionSession.GetSessionHandle(); + clientSessionHandle.ServerSession.Id["id"].AsGuid.Should().NotBeEmpty(); + clientSessionHandle.IsInTransaction.Should().BeTrue(); + } + [Fact] public async Task MongoSession_Dispose_ShouldDisposeSession() { diff --git a/src/Session/ISession.cs b/src/Session/ISession.cs index 81a7195..f399365 100644 --- a/src/Session/ISession.cs +++ b/src/Session/ISession.cs @@ -9,4 +9,7 @@ public interface ISession : IDisposable Task WithTransactionAsync( Func> action, CancellationToken cancellationToken); + + ITransactionSession StartTransaction( + CancellationToken cancellationToken); } diff --git a/src/Session/Internal/MongoSession.cs b/src/Session/Internal/MongoSession.cs index e149d63..01271c3 100644 --- a/src/Session/Internal/MongoSession.cs +++ b/src/Session/Internal/MongoSession.cs @@ -7,16 +7,14 @@ namespace MongoDB.Extensions.Session; internal sealed class MongoSession : ISession { + private readonly TransactionOptions _transactionOptions; private bool _disposed; - private static TransactionOptions TransactionOptions { get; } = new( - ReadConcern.Majority, - ReadPreference.Primary, - WriteConcern.WMajority.With(journal: true), - TimeSpan.FromSeconds(180)); - - public MongoSession(IClientSessionHandle clientSession) + public MongoSession( + IClientSessionHandle clientSession, + TransactionOptions transactionOptions) { + _transactionOptions = transactionOptions; Session = clientSession; } @@ -27,9 +25,15 @@ public Task WithTransactionAsync( CancellationToken cancellationToken) { return Session.WithTransactionAsync( - (_, ct) => action(this, ct), - TransactionOptions, - cancellationToken); + (_, ct) => action(this, ct), _transactionOptions, cancellationToken); + } + + public ITransactionSession StartTransaction( + CancellationToken cancellationToken) + { + Session.StartTransaction(_transactionOptions); + + return new MongoTransactionSession(Session, cancellationToken); } private void Dispose(bool disposing) diff --git a/src/Session/Internal/MongoSessionProvider.cs b/src/Session/Internal/MongoSessionProvider.cs index e12d049..b49f199 100644 --- a/src/Session/Internal/MongoSessionProvider.cs +++ b/src/Session/Internal/MongoSessionProvider.cs @@ -16,26 +16,19 @@ public MongoSessionProvider(TContext context) _mongoClient = context.Client; } - public Task BeginTransactionAsync( - CancellationToken cancellationToken) - { - return BeginTransactionAsync(true, cancellationToken); - } + protected virtual TransactionOptions TransactionOptions { get; } = new( + ReadConcern.Majority, + ReadPreference.Primary, + WriteConcern.WMajority.With(journal: true), + TimeSpan.FromSeconds(180)); - private async Task BeginTransactionAsync( - bool safeModeEnabled, + public async Task BeginTransactionAsync( CancellationToken cancellationToken) { IClientSessionHandle clientSession = await _mongoClient .StartSessionAsync(cancellationToken: cancellationToken); - var transactionOptions = new TransactionOptions( - ReadConcern.Majority, - ReadPreference.Primary, - WriteConcern.WMajority.With(journal: safeModeEnabled), - TimeSpan.FromSeconds(180)); - - clientSession.StartTransaction(transactionOptions); + clientSession.StartTransaction(TransactionOptions); return new MongoTransactionSession(clientSession, cancellationToken); } @@ -46,6 +39,6 @@ public async Task StartSessionAsync( IClientSessionHandle clientSession = await _mongoClient .StartSessionAsync(cancellationToken: cancellationToken); - return new MongoSession(clientSession); + return new MongoSession(clientSession, TransactionOptions); } } diff --git a/src/Session/Internal/MongoTransactionSession.cs b/src/Session/Internal/MongoTransactionSession.cs index 9835aa7..104cb83 100644 --- a/src/Session/Internal/MongoTransactionSession.cs +++ b/src/Session/Internal/MongoTransactionSession.cs @@ -5,7 +5,7 @@ namespace MongoDB.Extensions.Session; -internal class MongoTransactionSession : ITransactionSession +internal sealed class MongoTransactionSession : ITransactionSession { private readonly CancellationToken _cancellationToken; private bool _disposed; @@ -25,7 +25,7 @@ public async Task CommitAsync() await Session.CommitTransactionAsync(_cancellationToken); } - protected virtual void Dispose(bool disposing) + private void Dispose(bool disposing) { if (!_disposed) {