liveBook · Manning

Money transfer

As explained in .NET in Action, Second Edition

A money transfer is an operation that debits one account and credits another by a specified amount.

A money transfer credits one account and debits another by the same amount. When balances occupy separate database rows, both updates must succeed together: a database transaction commits both or rolls them back. This protects against a failed step, lost connection, or application crash. section 11.2.1

When a transfer fails

A naive `TransferAsync` credits the recipient and saves that change before debiting the sender. If the sender lacks funds, `DebitAsync` throws, but the credit has already been saved. A test starting both accounts at 100 and attempting to transfer 120 exposes the invalid balances. section 11.2.1

Listing 11.11 A transactional version of the BankRepository.TransferAsync
public async Task TransferAsync(
  string from, string to, decimal amt)
{
  using var tx = await
    _ctxt.Database.BeginTransactionAsync();    #1
  
  try
  {
    await CreditAsync(to, amt);                #2
    await DebitAsync(from, amt);
    await tx.CommitAsync();                    #3
  }
  catch                                        #4
  {
    await tx.RollbackAsync();                  #5
    _ctxt.ChangeTracker.Clear();               #6
    throw;                                     #7
  }
}

The transactional version begins a transaction before either update, commits after both succeed, and rolls back on failure. It also clears EF Core’s change tracker before rethrowing so tracked account state does not retain the failed changes. section 11.2.1

How .NET in Action, Second Edition covers it

How deep it goes
Works through asynchronous credit and debit methods, a failing test, and a transactional repair; does not develop concurrent-transfer handling.
Examples
Tests a 120-unit transfer between accounts initially holding 100 each to expose a credit left behind after insufficient funds.
What you can do after
Build it from scratch with EF Core transaction methods, then test that a failed transfer leaves both balances unchanged.
How it connects
Connects database transactions, EF Core change tracking, rollback, exceptions, and integration testing.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of .NET in Action, Second Edition. The section links point to the parts of the book it draws on.