Rinor
Rinor

Reputation: 1999

Why does DbContext in EF Core return changed entity after Transaction Rollback

I want to verify that Transaction is rolled back on the case of an exception. The below method can potentially throw an exception.

// method Checkout(user, reduceMoney, addBill)
using (var transaction = _botContext.Database.BeginTransaction())
{
    try
    {
        await FirstDbUpdate(user, reduceMoney);
        await SecondDbUpdate(user, addBill); // potential exception

        transaction.Commit();
    }
    catch (Exception ex)
    {
        // ...
    }
}

To verify the rollback I wrote this test:

[Test]
public async Task Test_TransactionFail_RevertedUserUpdate()
{
    // Arrange user{budget: 10}
    var user = await _userRepository.GetByName("John Doe");
    var reduceMoney = 10m;

    // Act - null causes an exception
    await _service.Checkout(user, reduceMoney, null);  

    // Assert
    var userRetrieved = await _userRepository.GetByName("John Doe");
    Assert.AreEqual(10, userRetrieved.Budget);
}

Assertion fails because the user has a budget of 0. i.e. it looks like the change was persisted, but in reality, it is not (which is the correct behavior).

So the question is why does DbContext return the not persisted data, and where does it get it from? Shouldn't the rollback have removed them?

Upvotes: 2

Views: 812

Answers (1)

ocrenaka
ocrenaka

Reputation: 192

Because you are in the some context instance, the query in Assert will load from the same instance instead to have a direct query to your database.

Try with other instance or reload it https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.changetracking.entityentry.reload?view=efcore-2.0

Upvotes: 1

Related Questions