Skip to content

Commit

Permalink
Add posibility to start transaction from session
Browse files Browse the repository at this point in the history
  • Loading branch information
glucaci committed Oct 3, 2023
1 parent 9a00a43 commit 0adc43e
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 28 deletions.
3 changes: 3 additions & 0 deletions src/Session.Abstractions/ISession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@ public interface ISession : IDisposable
Task<T> WithTransactionAsync<T>(
Func<ISession, CancellationToken, Task<T>> action,
CancellationToken cancellationToken);

ITransactionSession StartTransaction(
CancellationToken cancellationToken);
}
20 changes: 20 additions & 0 deletions src/Session.Tests/MongoSessionProviderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,26 @@ public async Task StartSessionAsync_ShouldStartSession()
clientSessionHandle.IsInTransaction.Should().BeFalse();
}

[Fact]
public async Task StartTransaction_ShouldBeginTransaction()
{
// Arrange
var dbContext = new TestDbContext(_mongoOptions);
ITestSessionProvider sessionProvider = new TestSessionProvider(dbContext);
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()
{
Expand Down
24 changes: 14 additions & 10 deletions src/Session/Internal/MongoSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -27,9 +25,15 @@ public MongoSession(IClientSessionHandle clientSession)
CancellationToken cancellationToken)
{
return Session.WithTransactionAsync<T>(
(_, 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)
Expand Down
25 changes: 9 additions & 16 deletions src/Session/Internal/MongoSessionProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace MongoDB.Extensions.Session;

public abstract class MongoSessionProvider<TContext> : ISessionProvider
public class MongoSessionProvider<TContext> : ISessionProvider
where TContext : IMongoDbContext
{
private readonly IMongoClient _mongoClient;
Expand All @@ -16,26 +16,19 @@ public MongoSessionProvider(TContext context)
_mongoClient = context.Client;
}

public Task<ITransactionSession> 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<ITransactionSession> BeginTransactionAsync(
bool safeModeEnabled,
public async Task<ITransactionSession> 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);
}
Expand All @@ -46,6 +39,6 @@ public MongoSessionProvider(TContext context)
IClientSessionHandle clientSession = await _mongoClient
.StartSessionAsync(cancellationToken: cancellationToken);

return new MongoSession(clientSession);
return new MongoSession(clientSession, TransactionOptions);
}
}
4 changes: 2 additions & 2 deletions src/Session/Internal/MongoTransactionSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace MongoDB.Extensions.Session;

internal class MongoTransactionSession : ITransactionSession
internal sealed class MongoTransactionSession : ITransactionSession
{
private readonly CancellationToken _cancellationToken;
private bool _disposed;
Expand All @@ -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)
{
Expand Down

0 comments on commit 0adc43e

Please sign in to comment.