public async Task RepositoriesCreatedOutsideAsyncContext_TransactionsAreTolerantToConcurrency() { var repoA = _mongoClient.GetRepository <MyStandaloneEntity>("a"); var repoB = _mongoClient.GetRepository <MyStandaloneEntity>("b"); var repoC = _mongoClient.GetRepository <MyStandaloneEntity>("c"); await repoA.InsertAsync(new MyStandaloneEntity("Jane", new SharedClass("Doe"))); await repoB.InsertAsync(new MyStandaloneEntity("John", new SharedClass("Doe"))); await repoC.InsertAsync(new MyStandaloneEntity("Janet", new SharedClass("Doe"))); var tasks = new Func <Task>[] { async() => { using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { await repoA.DeleteManyAsync(x => true); transaction.Complete(); } }, async() => { using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { await repoB.DeleteManyAsync(x => true); } }, async() => { await repoC.WithTransactionAsync(async() => { await repoC.DeleteManyAsync(x => true); }, TransactionType.TransactionScope); }, async() => { using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { var repoD = _mongoClient.GetRepository <MyStandaloneEntity>("d"); await Task.Delay(1); await MyStaticInserter.InsertDocument(new MyStandaloneEntity("Jeff", new SharedClass("Doe")), repoD); MyStaticInserter.InsertDocument(new MyStandaloneEntity("Jeff", new SharedClass("Doe")), repoD).Wait(); // No commit } }, } .AsParallel() .WithDegreeOfParallelism(4) .WithExecutionMode(ParallelExecutionMode.ForceParallelism) .Select(async x => await x()); await Task.WhenAll(tasks); var jane = await repoA.GetAll().SingleOrDefaultAsync(); var john = await repoB.GetAll().SingleOrDefaultAsync(); var janet = await repoC.GetAll().SingleOrDefaultAsync(); var jeff = await _mongoClient.GetRepository <MyStandaloneEntity>("d").GetAll().SingleOrDefaultAsync(); jane.Should().BeNull(); john.Name.Should().Be("John"); janet.Should().BeNull(); jeff.Should().BeNull(); }
public async Task ShouldUseTheRightSessionInAMultiThreadedScenarioWithExplicitTransaction() { var request1 = Task.Run(async() => { var repo = _mongoClient.GetRepository <DummyEntity>("tenant_a"); using (var transaction = repo.StartTransaction()) { await repo.InsertAsync(new DummyEntity("Hello!")); await transaction.CommitAsync(); } }); var request2 = Task.Run(async() => { var repo = _mongoClient.GetRepository <DummyEntity>("tenant_b"); using (var transaction = repo.StartTransaction()) { await Task.Run(async() => await repo.InsertAsync(new DummyEntity("Hola!"))); // No commit } }); var request3 = Task.Run(async() => { var repo = _mongoClient.GetRepository <DummyEntity>("tenant_a"); using (var transaction = repo.StartTransaction()) { await Task.Run(async() => await repo.InsertAsync(new DummyEntity("Hello again!"))); // No commit } }); var request4 = Task.Run(async() => { var repo = _mongoClient.GetRepository <DummyEntity>("tenant_a"); using (var transaction = repo.StartTransaction()) { await Task.Delay(50); await repo.InsertAsync(new DummyEntity("Hello good sir or madam!")); await transaction.CommitAsync(); } }); var request5 = Task.Run(async() => { var repo = _mongoClient.GetRepository <DummyEntity>("tenant_b"); using (var transaction = repo.StartTransaction()) { await MyStaticInserter.InsertDocument(new DummyEntity("Hola senor"), repo); MyStaticInserter.InsertDocument(new DummyEntity("Hola senor"), repo).Wait(); await transaction.CommitAsync(); } }); await Task.WhenAll(request1, request2, request3, request4, request5); var allDocumentsForTenantA = await _mongoClient.GetRepository <DummyEntity>("tenant_a").GetAll().ToListAsync(); var allDocumentsForTenantB = await _mongoClient.GetRepository <DummyEntity>("tenant_b").GetAll().ToListAsync(); allDocumentsForTenantA.Should().HaveCount(2); allDocumentsForTenantB.Should().HaveCount(2); allDocumentsForTenantA.Should().ContainSingle(x => x.MyProperty == "Hello!"); allDocumentsForTenantA.Should().ContainSingle(x => x.MyProperty == "Hello good sir or madam!"); allDocumentsForTenantB.Count(x => x.MyProperty == "Hola senor").Should().Be(2); }