CQRS.Tests.CQRS.EventSourcing.Sql.SqlServerEventStoreSessionTests.Serializes_access_to_an_aggregate_so_that_concurrent_transactions_succeed_even_if_history_has_been_read_outside_of_modifying_transactions C# (CSharp) Method

Serializes_access_to_an_aggregate_so_that_concurrent_transactions_succeed_even_if_history_has_been_read_outside_of_modifying_transactions() private method

        public void Serializes_access_to_an_aggregate_so_that_concurrent_transactions_succeed_even_if_history_has_been_read_outside_of_modifying_transactions()
        {
            var user = new User();
            user.Register("[email protected]", "password", Guid.NewGuid());
            using (var session = OpenSession(CreateStore()))
            {
                session.Save(user);
                user.ChangeEmail($"[email protected]");
                session.SaveChanges();
            }

            Action updateEmail = () =>
            {
                using (var session = OpenSession(CreateStore()))
                {
                    var prereadHistory = ((IEventStoreReader)session).GetHistory(user.Id);
                    using (var transaction = new TransactionScope())
                    {
                        var userToUpdate = session.Get<User>(user.Id);
                        userToUpdate.ChangeEmail($"newemail_{userToUpdate.Version}@somewhere.not");
                        Thread.Sleep(100);
                        session.SaveChanges();
                        transaction.Complete();
                    }//Sql duplicate key (AggregateId, Version) Exception would be thrown here if history was not serialized 
                }
            };

            var tasks = 1.Through(20).Select(_ => Task.Factory.StartNew(updateEmail)).ToArray();
            Task.WaitAll(tasks);

            using (var session = OpenSession(CreateStore()))
            {
                var userHistory = ((IEventStoreReader)session).GetHistory(user.Id).ToArray();//Reading the aggregate will throw an exception if the history is invalid.
                userHistory.Length.Should().Be(22);//Make sure that all of the transactions completed
            }
        }