Транзакция не работает с Web API. net core 2.2 - PullRequest
0 голосов
/ 26 марта 2020

У меня есть asyn c веб-API, который имеет службы и подключение к БД с использованием контекста EF. В одном из сервисов, где я внедряю контекст, используя DI, я хочу создать простой транзакционный сервис, такой как:

public async Task<int> ServiceMethod()
{
    using (var transaction = context.Database.BeginTransaction())
    {
         await context.Table1.AddAsync(new Table1());
         await context.SaveChangeAsync();

         CallOtherservice(context);
         await context.SaveChangeAsync();

         transaction.Commit();   
    }
}

CallOtherService(Context context)
{
     await context.Table2.AddAsync();
}

. Я теперь сменил CallOtherService (), чтобы вызвать исключение, и я ничего не ожидаю commit, но похоже, что изменения в Table1 сохраняются, несмотря на то, что транзакция должна их остановить. Я попытался вызвать Rollback () в инструкции try catch и использовать вместо нее TransactionScope (), но оба они были бесполезны. Кроме того, я заметил, что после вызова .BeginTransaction () context.Database.CurrentTransaction имеет значение null, что я считаю немного странным.

EDIT: метод, который я тестирую:

public async Task<int> AddMatchAsync(Models.Database.Match match)
        {
            //If match is null, nothing can be done
            if (match == null)
                return 0;
            else
            {
                using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    try
                    {
                        //If the match already exists, return its id
                        var dbId = await ExistsMatchAsync(match.HomeTeam.Name, match.AwayTeam.Name, match.Time);
                        if (dbId > 0)
                        {
                            log.Info($"Found match with id {dbId}");
                            return dbId;
                        }

                        //add computable data
                        match = await AttachMatchName(match);
                        match.Season = CommonServices.toSeason(match);

                        // Prepare the relational entities accordingly
                        match = PrepareTeamsForAddMatch(match).Result;
                        match = PrepareLeagueForAddMatch(match).Result;

                        //add the match and save it to the DB
                        await context.Matches.AddAsync(match);
                        await context.SaveChangesAsync();
                        log.Info($"Successfully added a new match! id: {match.Id}");

                        // Create new TeamLeagues entities if needed
                        leaguesService.CreateTeamLeaguesForNewMatchAsync(context, match);
                        await context.SaveChangesAsync();

                        scope.Complete();
                        return match.Id;
                    }
                    catch (Exception ex)
                    {
                        log.Error($"Error adding match - Rolling back: {ex}");
                        throw;
                    }

                }
            }
        }

и тест:

        [Test] 
        public void AddMatchSaveChangesTransaction()
        {
            //Arrange
            var exceptiontext = "This exception should prevent the match from being saved";
            var leagueServiceMock = new Mock<ILeaguesService>();
            leagueServiceMock.Setup(p => p.CreateTeamLeaguesForNewMatchAsync(It.IsAny<InFormCoreContext>(),It.IsAny<Match>()))
                .Throws(new Exception(exceptiontext));

            leagueServiceMock.Setup(p => p.GetLeagueAsync(It.IsAny<string>()))
                .ReturnsAsync((string name) => new League{Id = 1, Name = name });

            var match = new Match
            {
                HomeTeam = new Team { Name = "Liverpool" },
                AwayTeam = new Team { Name = "Everton" },
                League = new League { Name = "PL", IsSummer = true },
                Time = DateTime.UtcNow,
                HomeGoals = 3,
                AwayGoals = 0
            };
            var mcount = context.Matches.Count();

            //Act
            var matchService = new MatchesService(context, leagueServiceMock.Object, new LogNLog(), TeamsService);

            //Assert
            var ex = Assert.ThrowsAsync<Exception>(async () => await matchService.AddMatchAsync(match));
            Assert.AreEqual(ex.Message, exceptiontext); 

            Assert.AreEqual(mcount, context.Matches.Count(), "The match has been added - the transaction does not work");
        }`
```
...