public static void Withdraw(string number, string pin, decimal amount) { TransactionOptions options = new TransactionOptions(); options.IsolationLevel = IsolationLevel.RepeatableRead; TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, options); using (scope) { ATMEntities context = new ATMEntities(); using (context) { var account = context.CardAccounts.First(x => x.CardNumber == number && x.CardPIN == pin); if (account != null) { if (amount <= account.CardCash && amount > 0) { account.CardCash -= amount; AddTransaction.Add(number, DateTime.Now, amount, context); } } context.SaveChanges(); scope.Complete(); } } }
static void Main() { using (ATMEntities context = new ATMEntities()) { Add("999999", DateTime.Now, 100m, context); } }
public static void Add(string number, DateTime date, decimal ammount, ATMEntities context) { CardHistoryLog log = new CardHistoryLog(); log.CardNumber = number; log.OperationDate = date; log.amount = ammount; context.CardHistoryLogs.Add(log); context.SaveChanges(); }
public void WithdrawTo0() { decimal money = 1000m; string number = "1111111111"; string cardPin = "1111"; using (ATMEntities contextOut = new ATMEntities()) { contextOut.CardAccounts.Add(new CardAccount() { CardCash = money, CardNumber = number, CardPIN = cardPin }); contextOut.SaveChanges(); RepeatableRead.Withdraw(number, cardPin, money); var actual = (from c in contextOut.CardAccounts select c).First(); Assert.AreEqual(0, actual.CardCash); contextOut.Dispose(); } }
public void CheckRecordAmount() { decimal money = 2000m; decimal toWithdraw = 1000m; string number = "1111111111"; string cardPin = "1111"; using (ATMEntities contextOut = new ATMEntities()) { contextOut.CardAccounts.Add(new CardAccount() { CardCash = money, CardNumber = number, CardPIN = cardPin }); contextOut.SaveChanges(); RepeatableRead.Withdraw(number, cardPin, toWithdraw); var actual = (from c in contextOut.CardHistoryLogs select c).First(); Assert.AreEqual(1000, actual.amount); contextOut.Dispose(); } }
private static void SaveTransaction(string cardNumber, DateTime timestamp, decimal amount) { var context = new ATMEntities(); using (context) { var log = new TransactionLog() { CardNumber = cardNumber, TransactionDate = timestamp, Amount = amount }; context.TransactionLogs.Add(log); context.SaveChanges(); } }
public static void WithdrawFunds(string pin, string cardNumber, decimal amount) { var context = new ATMEntities(); using (var contextTransaction = context.Database.BeginTransaction(IsolationLevel.RepeatableRead)) { bool isValid = false; var account = context.CardAccounts .Where(c => c.CardNumber == cardNumber) .Select(c => new { c.CardNumber, c.CardPIN, c.CardCash }) .FirstOrDefault(); do { string failureCode = ""; try { if (account == null) { failureCode = "account"; throw new Exception("Something went wrong with your data."); } if (account.CardPIN != pin) { failureCode = "pin"; throw new Exception("Incorrect PIN."); } if (account.CardCash < amount) { failureCode = "insufficient"; throw new Exception("Insufficient funds."); } if (amount <= 0) { failureCode = "zero"; throw new Exception("Withdraw amount must be positive."); } if (account.CardNumber == null) { failureCode = "number"; throw new Exception("Incorrect card number."); } isValid = true; var accountToUpdate = context.CardAccounts .Where(c => c.CardNumber == cardNumber) .FirstOrDefault(); Console.WriteLine("Funds before: " + accountToUpdate.CardCash); var updatedAmount = account.CardCash - amount; accountToUpdate.CardCash = updatedAmount; context.SaveChanges(); contextTransaction.Commit(); SaveTransaction(cardNumber, DateTime.Now, amount); Console.WriteLine("---Withdrawal successful.---"); Console.WriteLine("Funds after: " + accountToUpdate.CardCash); } catch (Exception e) { isValid = false; Console.WriteLine(e.Message); switch (failureCode) { case "account": Console.Write("PIN: "); pin = Console.ReadLine(); Console.Write("Card number: "); cardNumber = Console.ReadLine(); Console.Write("Amount: "); amount = decimal.Parse(Console.ReadLine()); break; case "pin": Console.Write("PIN: "); pin = Console.ReadLine(); break; case "insufficient": Console.Write("New amount: "); amount = decimal.Parse(Console.ReadLine()); break; case "zero": Console.Write("New amount: "); amount = decimal.Parse(Console.ReadLine()); break; case "number": Console.Write("Card number: "); cardNumber = Console.ReadLine(); break; } } } while (!isValid); } }