public async Task <ActionResult <Transaction> > PostTransactionDetails(Transaction transaction)
        {
            var tran = new Transaction();

            tran.WalletId    = transaction.WalletId;
            tran.Amount      = transaction.Amount;
            tran.Destination = transaction.Destination;
            tran.Type        = transaction.Type;
            tran.TimeCreate  = DateTime.Now;
            tran.WalletNo    = transaction.WalletNo;

            var wallet = _context.Wallets.FirstOrDefault(x => x.WalletNo == transaction.WalletNo);

            if (wallet == null)
            {
                return(NotFound());
            }

            wallet.Balance    = wallet.Balance + tran.Amount;
            wallet.TimeUpdate = DateTime.Now;
            _context.Transactions.Add(tran);
            _context.SaveChanges();

            var transactionResult = _context.Transactions
                                    .FirstOrDefault(transaction => transaction.TransId == tran.TransId);

            if (transactionResult == null)
            {
                return(NotFound());
            }

            return(transactionResult);
        }
        public async Task <IActionResult> PutTransaction(int id, Transaction transaction)
        {
            if (id != transaction.TransId)
            {
                return(BadRequest());
            }

            // _context.Entry(todoItem).State = EntityState.Modified;
            var tran = await _context.Transactions.FindAsync(id);

            if (tran == null)
            {
                return(NotFound());
            }

            tran.WalletId    = transaction.WalletId;
            tran.WalletNo    = transaction.WalletNo;
            tran.Amount      = transaction.Amount;
            tran.Destination = transaction.Destination;
            tran.Type        = transaction.Type;
            tran.TimeCreate  = DateTime.Now;

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException) when(!TransactionExists(id))
            {
                return(NotFound());
            }

            return(NoContent());
        }
        public ActionResult <Transaction> TopUp2(Transaction transaction)
        {
            var wallet            = new Wallet();
            var tran              = new Transaction();
            var connectionString  = "Server=DESKTOP-AQCHHJ8;Initial Catalog=WalletDB;Trusted_Connection=True;";
            var myDistributedLock = new SqlDistributedLock(transaction.WalletNo, /* _context.Database.GetConnectionString()*/ connectionString);

            tran.WalletId    = transaction.WalletId;
            tran.Amount      = transaction.Amount;
            tran.Destination = transaction.Destination;
            tran.Type        = transaction.Type;
            tran.TimeCreate  = DateTime.Now;
            tran.WalletNo    = transaction.WalletNo;
            tran.BalanceN    = 0;
            tran.BalanceO    = 0;

            using (myDistributedLock.Acquire())
            {
                intNum++;
                _context.Transactions.Add(tran);
                _context.SaveChanges();

                wallet = _context.Wallets.FirstOrDefault(x => x.WalletNo == transaction.WalletNo);

                wallet.Balance    = wallet.Balance + tran.Amount;
                wallet.TimeUpdate = DateTime.Now;
                tran.BalanceN     = wallet.Balance;
                tran.BalanceO     = wallet.Balance - tran.Amount;
                _context.SaveChanges();

                tran.Wallet = wallet;
                System.Diagnostics.Debug.WriteLine(" Thread Id = " + Thread.CurrentThread.ManagedThreadId + " TransId = " + tran.TransId + " WalletId = " + tran.WalletId + " Balance = " + tran.Wallet.Balance + "  Count= " + intNum);
            }
            return(tran);
        }
        public static int PostTransactionTest(Transaction transaction)
        {
            Queue <Transaction> queue = new Queue <Transaction>();

            queue.Enqueue(transaction);
            System.Diagnostics.Debug.WriteLine(queue.Count());
            return(queue.Count());

            //  ShortStringDictionary mySSC = new ShortStringDictionary();
            //     mySSC.Add("One", "a");
        }
        // not use
        public void ThreadProc2(Transaction transaction)
        {
            Wallet wallet = _context.Wallets.FirstOrDefault(x => x.WalletNo == transaction.WalletNo);

            System.Diagnostics.Debug.WriteLine(wallet.Balance);
            wallet.Balance = wallet.Balance + transaction.Amount;
            System.Diagnostics.Debug.WriteLine(wallet.Balance);
            wallet.TimeUpdate = DateTime.Now;
            _context.SaveChanges();
            System.Diagnostics.Debug.WriteLine("Dequeue()");
            Queue <Transaction> queue = new Queue <Transaction>();

            queue.Dequeue();
        }
        public async Task <ActionResult <WalletWithTransactions> > ThreadProc3(Transaction transaction)
        {
            // Thread thread = new Thread(() => ThreadProc(transaction));
            int result = AddTransaction(transaction);

            var resultTransaction = _context.Transactions
                                    .Where(x => x.TransId == result)
                                    .FirstOrDefault();

            WalletWithTransactions walletUpdate = null;

            BackgroundPrinter.AddTransaction(resultTransaction);

            return(walletUpdate);
        }
        public void updateBalance(Transaction resultTransaction)
        {
            using (var scope = scopeFactory.CreateScope())
            {
                var dBContext = scope.ServiceProvider.GetRequiredService <WalletDBContext>();

                Wallet wallet = dBContext.Wallets
                                .FirstOrDefault(x => x.WalletId == resultTransaction.WalletId);

                wallet.Balance    = wallet.Balance + resultTransaction.Amount;
                wallet.TimeUpdate = DateTime.Now;
                dBContext.SaveChanges();

                TempTrans(resultTransaction.TransId, wallet.Balance);
            }
        }
        public int AddTransaction(Transaction transaction)
        {
            //Thread thread = Thread.CurrentThread;
            Transaction tran = new Transaction();

            tran.WalletId    = transaction.WalletId;
            tran.Amount      = transaction.Amount;
            tran.Destination = transaction.Destination;
            tran.Type        = transaction.Type;
            tran.TimeCreate  = DateTime.Now;
            tran.WalletNo    = transaction.WalletNo;
            _context.Transactions.Add(tran);
            _context.SaveChanges();

            return(tran.TransId);
        }
        public async Task <ActionResult <Transaction> > PostTransaction(Transaction transaction)
        {
            DateTime localDate = DateTime.Now;
            var      trans     = new Transaction
            {
                WalletId    = transaction.WalletId,
                WalletNo    = transaction.WalletNo,
                Destination = transaction.Destination,
                Amount      = transaction.Amount,
                Type        = transaction.Type,
                TimeCreate  = localDate
            };

            _context.Transactions.Add(trans);
            await _context.SaveChangesAsync();

            //return CreatedAtAction("GetTodoItem", new { id = todoItem.Id }, todoItem);
            return(CreatedAtAction("GetTransaction", new { id = trans.TransId }, trans));
        }
        private int saveTransaction(Transaction transaction)
        {
            var tran = new Transaction();

            tran.WalletId    = transaction.WalletId;
            tran.Amount      = transaction.Amount;
            tran.Destination = transaction.Destination;
            tran.Type        = transaction.Type;
            tran.TimeCreate  = DateTime.Now;
            tran.WalletNo    = transaction.WalletNo;

            var wallet = _context.Wallets.FirstOrDefault(x => x.WalletNo == transaction.WalletNo);

            wallet.Balance    = wallet.Balance + tran.Amount;
            wallet.TimeUpdate = DateTime.Now;
            _context.Transactions.Add(tran);
            _context.SaveChanges();
            return(tran.TransId);
        }
        public ActionResult <Transaction> TopUp(Transaction transaction)
        {
            lock (balanceLock)
            {
                var wallet = new Wallet();
                var tran   = new Transaction();

                tran.WalletId    = transaction.WalletId;
                tran.Amount      = transaction.Amount;
                tran.Destination = transaction.Destination;
                tran.Type        = transaction.Type;
                tran.TimeCreate  = DateTime.Now;
                tran.WalletNo    = transaction.WalletNo;
                tran.BalanceO    = 0;
                tran.BalanceN    = 0;

                _context.Transactions.Add(tran);
                _context.SaveChanges();

                var commandText = "BEGIN TRANSACTION; " +
                                  " UPDATE[dbo].[Wallet] SET balance = balance + @Amount2 WHERE wallet_id = @myWalletId   " +
                                  " UPDATE[dbo].[Transaction] SET balance_o = T2.balance - @Amount , balance_n = T2.balance " +
                                  " FROM[dbo].[Transaction] T1 , [dbo].[Wallet] T2            " +
                                  " WHERE trans_id = @myTransId     " +
                                  " COMMIT;";

                var Amount     = new SqlParameter("@Amount", tran.Amount);
                var Amount2    = new SqlParameter("@Amount2", tran.Amount);
                var myWalletId = new SqlParameter("@myWalletId", tran.WalletId);
                var myTransId  = new SqlParameter("@myTransId", tran.TransId);
                _context.Database.ExecuteSqlRaw(commandText, new[] { Amount2, myWalletId, Amount, myTransId });
                _context.SaveChanges();


                var thing = _context.Transactions.Find(tran.TransId);
                _context.Entry(thing).State = EntityState.Detached;
                var result = _context.Transactions.FirstOrDefault(x => x.TransId == tran.TransId);

                return(result);
            }
        }
        public static void  AddTransaction(Transaction resultTransaction)
        {
            //Thread.Sleep(100);
            System.Diagnostics.Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
            queueTrans.Enqueue(resultTransaction);

            while (queueBalance.Count == 0)
            {
                Thread.Sleep(100);
            }

            while (queueBalance.Peek().TransId != resultTransaction.TransId)
            {
                Thread.Sleep(100);
            }

            // System.Diagnostics.Debug.WriteLine($" queueBalance Count Down = {queueBalance.Count} ");
            // System.Diagnostics.Debug.WriteLine($" queueBalance ALL COUNT = {queueBalance2.Count} ");
            //   return
            queueBalance.Dequeue();
        }
        public async Task <ActionResult <Transaction> > PostTransactionDe(Transaction transaction)
        {
            try
            {
                //  using (var scope = new TransactionScope(TransactionScopeOption.Required, new
                //  TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead }))
                // using (TransactionScope ts = new TransactionScope())
                using (TransactionScope ts = CreateTransactionScope())
                {
                    var tran = new Transaction();
                    tran.WalletId    = transaction.WalletId;
                    tran.Amount      = transaction.Amount;
                    tran.Destination = transaction.Destination;
                    tran.Type        = transaction.Type;
                    tran.TimeCreate  = DateTime.Now;
                    tran.WalletNo    = transaction.WalletNo;

                    var wallet = _context.Wallets.FirstOrDefault(x => x.WalletNo == transaction.WalletNo);

                    wallet.Balance    = wallet.Balance + tran.Amount;
                    wallet.TimeUpdate = DateTime.Now;
                    _context.Transactions.Add(tran);
                    _context.SaveChanges();
                    // scope.Complete();
                    var transactionResult = _context.Transactions
                                            //    .Include(transaction => transaction.Wallet)
                                            //    .ThenInclude(transaction => transaction.Customer)
                                            .FirstOrDefault(transaction => transaction.TransId == tran.TransId);

                    ts.Complete();
                    return(transactionResult);
                }
            }
            catch (Exception)
            {
                return(NotFound());
            }
        }
        public ActionResult <Transaction> TopUp1(Transaction transaction)
        {
            var wallet = new Wallet();
            var tran   = new Transaction();
            var result = new Transaction();

            tran.WalletId    = transaction.WalletId;
            tran.Amount      = transaction.Amount;
            tran.Destination = transaction.Destination;
            tran.Type        = transaction.Type;
            tran.TimeCreate  = DateTime.Now;
            tran.WalletNo    = transaction.WalletNo;
            tran.BalanceO    = 0;
            tran.BalanceN    = 0;

            lock (balanceLock)
            {
                intNum++;
                _context.Transactions.Add(tran);
                _context.SaveChanges();

                wallet = _context.Wallets.FirstOrDefault(x => x.WalletNo == transaction.WalletNo);

                wallet.Balance    = wallet.Balance + tran.Amount;
                wallet.TimeUpdate = DateTime.Now;
                tran.BalanceN     = wallet.Balance;
                tran.BalanceO     = wallet.Balance - tran.Amount;
                _context.SaveChanges();

                result        = _context.Transactions.FirstOrDefault(x => x.TransId == tran.TransId);
                result.Wallet = wallet;
                System.Diagnostics.Debug.WriteLine(" Thread Id = " + Thread.CurrentThread.ManagedThreadId + " TransId = " + result.TransId + " WalletId = " + result.WalletId + " Balance = " + result.Wallet.Balance + "  Count= " + intNum);

                return(result);
            }
        }
        public async Task <ActionResult <Transaction> > PostTransactionDet(Transaction transaction)
        {
            var tran = new Transaction();

            tran.WalletId    = transaction.WalletId;
            tran.Amount      = transaction.Amount;
            tran.Destination = transaction.Destination;
            tran.Type        = transaction.Type;
            tran.TimeCreate  = DateTime.Now;
            tran.WalletNo    = transaction.WalletNo;
            _context.Transactions.Add(tran);
            //var wallet = _context.Wallets.FirstOrDefault(x => x.WalletNo == transaction.WalletNo);
            //wallet.Balance = wallet.Balance + tran.Amount;
            //wallet.TimeUpdate = DateTime.Now;
            _context.SaveChanges();

            // Thread thread = new Thread(() => ThreadProc(transaction));
            Queue <Transaction> queue = new Queue <Transaction>();

            queue.Enqueue(tran);
            System.Diagnostics.Debug.WriteLine(queue.Peek().TransId);
            System.Diagnostics.Debug.WriteLine(queue.Count);

            if (queue.Count > 0)
            {
                Thread.Sleep(1000);
            }

            while (queue.Peek().TransId != tran.TransId)
            {
                System.Diagnostics.Debug.WriteLine(queue.Peek().TransId == tran.TransId);

                Thread.Sleep(1000);
            }
            System.Diagnostics.Debug.WriteLine(queue.Peek().TransId == tran.TransId);

            var transactionResult = new Transaction();

            if (queue.Peek().TransId == tran.TransId)
            {
                System.Diagnostics.Debug.WriteLine(queue.Peek().TransId + " " + tran.TransId);

                /* Thread thread = new Thread(() => ThreadProc2(tran));
                 * System.Diagnostics.Debug.WriteLine("threadStart");
                 * thread.Start();
                 *
                 * thread.Join();
                 * System.Diagnostics.Debug.WriteLine("Join");
                 * transactionResult = _context.Transactions
                 *    .FirstOrDefault(transaction => transaction.TransId == tran.TransId);
                 */

                System.Diagnostics.Debug.WriteLine("start");
                Wallet wallet = _context.Wallets.FirstOrDefault(x => x.WalletNo == transaction.WalletNo);
                System.Diagnostics.Debug.WriteLine("1st " + wallet.Balance);
                wallet.Balance = wallet.Balance + transaction.Amount;
                System.Diagnostics.Debug.WriteLine("2nd " + wallet.Balance);
                wallet.TimeUpdate = DateTime.Now;

                _context.SaveChanges();
                System.Diagnostics.Debug.WriteLine("Dequeue()");
                queue.Dequeue();
            }
            return(transactionResult);
        }