public override TransactionStatistics.TransactionStatisticsInternal GetTransactionStatistics(long Identifier) { TransactionStatistics stats = TransactionStatistics.TransactionList[Identifier]; stats.UpdateInternals(); return(stats.StatisticsInternal); }
public void ExecuteTransaction(IList <DataRequest> requests) { var request = new TransactionRequest(requests) { IsSingleStage = true, TransactionId = Guid.NewGuid() }; TransactionStatistics.ExecutedAsSingleStage(); var response = Channel.SendRequest(request); if (response is NullResponse) { return; } if (response is ExceptionResponse exResponse) { if (exResponse.ExceptionType != ExceptionType.FailedToAcquireLock) { throw new CacheException(exResponse.Message, exResponse.ExceptionType); } } TransactionStatistics.NewTransactionCompleted(); }
public void ExecuteTransaction(IList <DataRequest> requests) { // the same connector will not execute transactions in parallel lock (_transactionSync) { var status = new TransactionState(); status.Initialize(requests, CacheClients); status.CheckStatus(TransactionState.Status.Initialized); status.TryExecuteAsSingleStage(); if (status.CurrentStatus == TransactionState.Status.Completed) { TransactionStatistics.ExecutedAsSingleStage(); return; } // stage zero : send the transaction request to the servers and wait for them to acquire write locks status.AcquireLock(); status.CheckStatus(TransactionState.Status.LocksAcquired); // first stage: the durable transaction is written in the transaction log status.ProceedWithFirstStage(); // second stage: commit or rollback only the servers that processed successfully the first stage // (if a server answered with an exception response the transaction was already rolled back on this server) if (status.CurrentStatus == TransactionState.Status.FirstStageCompleted) { // commit the transaction status.CommitSecondStage(); status.CheckStatus(TransactionState.Status.SecondStageCompleted); // close the transaction status.CloseTransaction(); status.CheckStatus(TransactionState.Status.Completed); TransactionStatistics.NewTransactionCompleted(); } else { status.Rollback(); throw new CacheException( $"Error in two stage transaction. The transaction was successfully rolled back: {status.ExceptionType}", status.ExceptionType); } } }
public List <TransactionStatistics> GetStats(DateTime date) { var transacStatsList = new List <TransactionStatistics>(); var transacs = _ctx.Transactions.Where(t => t.Date.Year == date.Year).ToList(); for (var i = 1; i <= 12; i++) { var monthlyTransacStats = new TransactionStatistics { Month = i - 1 }; var i1 = i; var transacsThisMonth = transacs.Where(t => t.Date.Month == i1); foreach (var transactionOfMonth in transacsThisMonth) { var transaclyStats = new TransactionStatistics(); foreach (var transactionItem in transactionOfMonth.TransactionItems) { var transacItemlyStats = new TransactionStatistics(); switch (transactionOfMonth.TransactionType) { case TransactionType.Sale: // profit/loss is only calculated duting a sale // this is done by getting the difference between an item's // buying and selling price if (transactionItem.Item.Deleted <= 0) { transacItemlyStats.Sales += transactionItem.Amount; transacItemlyStats.PurchaseCost += transactionItem.Item.PurchaseCost * transactionItem.Quantity; } break; case TransactionType.Purchase: // this is to show how much was spent buying stuff // operational cost, i think transacItemlyStats.Purchases += transactionItem.Amount; break; default: throw new Exception("Invalid TransactionType"); } // for each transactionItem, add its stats to the containing transaction's stats transaclyStats.Sales += transacItemlyStats.Sales; transaclyStats.PurchaseCost += transacItemlyStats.PurchaseCost; transaclyStats.Purchases += transacItemlyStats.Purchases; } // for each transaction, add its stats to that month's transaction stats monthlyTransacStats.Sales += transaclyStats.Sales; monthlyTransacStats.PurchaseCost += transaclyStats.PurchaseCost; monthlyTransacStats.Purchases += transaclyStats.Purchases; } // calculate profit for that month, and add that month's stats to list of monthly stats monthlyTransacStats.ProfitLoss = monthlyTransacStats.Sales - monthlyTransacStats.PurchaseCost; transacStatsList.Add(monthlyTransacStats); } return(transacStatsList); }
public void Init() { for (var i = 0; i < ServerCount; i++) { if (Directory.Exists($"server{i:D2}")) { Directory.Delete($"server{i:D2}", true); } } StartServers(); TransactionStatistics.Reset(); }
private static void CalculateAverageGainAndLossOnTransaction(SimulationResultDto resultDto, IList <int> companyIds) { var transactionDiffs = companyIds.ToDictionary(companyId => companyId, companyId => 0m); var gain = 0m; var loss = 0m; int successes = 0; int losses = 0; TransactionStatistics stats = new TransactionStatistics(); foreach (var trans in resultDto.TransactionsLog) { if (trans.Action == SignalAction.Buy) { transactionDiffs[trans.CompanyId] += trans.Quantity * trans.Price; } else if (trans.Action == SignalAction.Sell) { decimal buyValue = transactionDiffs[trans.CompanyId]; decimal sellValue = trans.Quantity * trans.Price; transactionDiffs[trans.CompanyId] = 0; var diff = sellValue - buyValue; if (diff > 0m) { gain += diff; successes++; } else { loss += diff; losses++; } } } if (successes + losses != 0) { stats.SuccessTransactionPercentage = Math.Round(100 * ((double)successes) / (successes + losses), 2); stats.FailedTransactionPercentage = Math.Round(100 * ((double)losses) / (successes + losses), 2); } else { stats.SuccessTransactionPercentage = 0; stats.FailedTransactionPercentage = 0; } stats.AverageGainOnTransaction = new AverageTransactionResult(gain, successes); stats.AverageLossOnTransaction = new AverageTransactionResult(loss, losses); resultDto.TransactionStatistics = stats; }
private static void PerfTest(Connector connector) { TransactionStatistics.Reset(); // first delete all data to start with a clean database connector.AdminInterface().DropDatabase(); connector.DeclareCollection <Account>(); connector.DeclareCollection <MoneyTransfer>(); var accounts = connector.DataSource <Account>(); // create the accounts for (int i = 0; i < TestIterations; i++) { accounts.Put(new Account { Id = i, Balance = 1000 }); } var tids = Enumerable.Range(0, TestIterations).ToArray(); try { tids = connector.GenerateUniqueIds("transfer_id", TestIterations); } catch (Exception) { // ignore (means testing with non persistent server) } var rand = new Random(); int failed = 0; var sw = new Stopwatch(); sw.Start(); for (int i = 0; i < TestIterations; i++) { var src = rand.Next(1, 1000); var dst = src + 1 > 999? src - 1:src + 1; var transferred = rand.Next(1, 1000); var srcAccount = accounts[src]; var dstAccount = accounts[dst]; srcAccount.Balance -= transferred; dstAccount.Balance += transferred; var transaction = connector.BeginTransaction(); transaction.UpdateIf(srcAccount, account => account.Balance >= transferred); transaction.Put(dstAccount); transaction.Put(new MoneyTransfer { Amount = transferred, Date = DateTime.Today, SourceAccount = src, DestinationAccount = dst, Id = tids[i] }); try { transaction.Commit(); } catch (CacheException e) { if (e.IsTransactionException) { failed++; } } } sw.Stop(); Console.WriteLine($"{TestIterations} transactions took {sw.ElapsedMilliseconds} milliseconds. Rolled back transactions: {failed}. "); var stats = TransactionStatistics.AsString(); Console.WriteLine(stats); // check that all accounts have positive balance var negatives = accounts.Count(acc => acc.Balance < 0); if (negatives > 0) { Console.WriteLine("Some accounts have negative balance"); } else { Console.WriteLine("All accounts have positive balance"); } }
public IActionResult Statistics() { TransactionStatistics statistics = foxCoinService.GetStatistics(); return(View(statistics)); }
public void No_deadlock_if_same_objects_are_updated_in_parallel_by_multiple_clients() { List <Account> myAccounts; using (var connector = new Connector(_clientConfig)) { var accounts = connector.DataSource <Account>(); var accountIds = connector.GenerateUniqueIds("account_id", 2); accounts.Put(new Account { Id = accountIds[0], Balance = 1000 }); accounts.Put(new Account { Id = accountIds[1], Balance = 0 }); myAccounts = accounts.ToList(); } Parallel.Invoke( () => { using (var connector1 = new Connector(_clientConfig)) { for (var i = 0; i < 100; i++) { var transfer = new MoneyTransfer { Amount = 10, Date = DateTime.Today, SourceAccount = myAccounts[0].Id, DestinationAccount = myAccounts[1].Id }; myAccounts[0].Balance -= 10; myAccounts[1].Balance += 10; var transaction = connector1.BeginTransaction(); transaction.Put(myAccounts[0]); transaction.Put(myAccounts[1]); transaction.Put(transfer); transaction.Commit(); } } }, () => { using (var connector2 = new Connector(_clientConfig)) { for (var i = 0; i < 100; i++) { var transfer = new MoneyTransfer { Amount = 10, Date = DateTime.Today, SourceAccount = myAccounts[0].Id, DestinationAccount = myAccounts[1].Id }; myAccounts[0].Balance -= 10; myAccounts[1].Balance += 10; var transaction = connector2.BeginTransaction(); transaction.Put(myAccounts[0]); transaction.Put(myAccounts[1]); transaction.Put(transfer); transaction.Commit(); } } }, () => { using (var connector3 = new Connector(_clientConfig)) { for (var i = 0; i < 100; i++) { var transfer = new MoneyTransfer { Amount = 10, Date = DateTime.Today, SourceAccount = myAccounts[0].Id, DestinationAccount = myAccounts[1].Id }; myAccounts[0].Balance -= 10; myAccounts[1].Balance += 10; var transaction = connector3.BeginTransaction(); transaction.Put(myAccounts[0]); transaction.Put(myAccounts[1]); transaction.Put(transfer); transaction.Commit(); } } }); TransactionStatistics.Display(); using (var connector = new Connector(_clientConfig)) { var accounts = connector.DataSource <Account>(); myAccounts = accounts.ToList(); Console.WriteLine($"balance1={myAccounts[0].Balance} balance2={myAccounts[1].Balance}"); Assert.AreEqual(1000, myAccounts[0].Balance + myAccounts[1].Balance); } }
public async Task <TransactionResponse> SaveAsync(Guid playerId, IEnumerable <Transaction> transactions) { if (transactions.Count() == 0) { return(new TransactionResponse("Empty transactions")); } var existingPlayer = await _playerRepository.FindByIdAsync(playerId); if (existingPlayer == null) { return(new TransactionResponse("Player not exist")); } try { TransactionStatistics transactionStatistics = new TransactionStatistics(); // traverse through transactions foreach (var transaction in transactions) { try { transaction.PlayerId = playerId; transaction.Player = existingPlayer; var existingTransaction = await _transactionRepository.FindByIdAsync(transaction.TransactionId); if (existingTransaction == null) { // execute transaction await _transactionCommand.ExecuteAction(transaction); // create a new instance of the transaction in the repository transaction.Status = ETransactionStatus.Succeed; await _transactionRepository.AddAsync(transaction); // update successfully processed transaction statistics transactionStatistics.AppliedTransactions.Add(transaction.TransactionId); } else { // duplicated transaction => return cached result if (existingTransaction.Status == ETransactionStatus.Succeed) { transactionStatistics.AppliedTransactions.Add(transaction.TransactionId); } else { transactionStatistics.FailedTransactions.Add(new FailedTransaction { TransactionId = transaction.TransactionId, Message = existingTransaction.Message }); } } } catch (Exception ex) { // update failed transaction statistics transactionStatistics.FailedTransactions.Add(new FailedTransaction { TransactionId = transaction.TransactionId, Message = ex.Message }); transaction.Status = ETransactionStatus.Failed; transaction.Message = ex.Message; await _transactionRepository.AddAsync(transaction); } } // story changes await _unitOfWork.CompleteAsync(); return(new TransactionResponse(transactionStatistics)); } catch (Exception ex) { return(new TransactionResponse($"An error occurred when saving the transaction: {ex.Message}")); } }