コード例 #1
0
        public void AddCommandWaitingQueue(Transactions Transactions, string Command)
        {
            // Adiciona a transação à fila quando ainda não existir
            TransactionQueueCommand transactionQueueCommand = null;

            if (!WaitingTransactionsList.ContainsKey(Transactions.TransactionNumber))
            {
                Transactions.LockType   = TransactionTypeLock.Waiting;
                transactionQueueCommand = new TransactionQueueCommand(Transactions);
                WaitingTransactionsList.Add(Transactions.TransactionNumber, transactionQueueCommand);
            }
            // Retorna a fila de Commands da transação.
            else
            {
                transactionQueueCommand = WaitingTransactionsList[Transactions.TransactionNumber];
            }

            // Adiciona Command à fila de espera da transação.
            transactionQueueCommand.AddComamand(Command);
            AddOutPut("Comando: " + Command + " adicionado à fila de espera.");
        }
コード例 #2
0
        private string CheckDeadLock(int TransactionNumber, string Dado, List <int> TransacoesWaiting)
        {
            string retorno = "-1|x";
            DataLockTransactions TransactionsUsingData;

            // Se não existir o dado é pq a transação já foi abortada
            if (TransactionDataLock.ContainsKey(Dado))
            {
                TransactionsUsingData = TransactionDataLock[Dado];
                foreach (var transactionNumber in TransactionsUsingData.ReturnTransactions())
                {
                    // Não verifica a própria transação
                    if (!transactionNumber.Equals(TransactionNumber))
                    {
                        // Adiciona na lista e verifica se ocorreu dead lock.
                        if (TransactionsList[TransactionNumber].LockType.Equals(TransactionTypeLock.Waiting))
                        {
                            if (TransacoesWaiting.Contains(TransactionNumber))
                            {
                                // Elimina deadlock
                                int eliminatedTransaction = RemoveDeadLock(TransacoesWaiting);
                                retorno = eliminatedTransaction + "|" + ReturnTransactionsCycle(TransacoesWaiting, eliminatedTransaction);
                            }
                            else
                            {
                                TransacoesWaiting.Add(TransactionNumber);
                                // Retorna dado que a transação está espera.
                                TransactionQueueCommand commandsTransactions = WaitingTransactionsList[TransactionNumber];
                                // Verifica pendencias desta transação.
                                retorno = CheckDeadLock(TransactionNumber, commandsTransactions.WaitingData, TransacoesWaiting);
                            }
                        }
                    }
                }
            }
            return(retorno);
        }
コード例 #3
0
        private void CheckWaitingQueue()
        {
            // Analisa primeiro comando de cada transação.
            List <int> excludes = new List <int>();

            foreach (var TransactionNumber in WaitingTransactionsList.Keys)
            {
                TransactionQueueCommand commandsTransactions = WaitingTransactionsList[TransactionNumber];
                if (!commandsTransactions.Transaction.LockType.Equals(TransactionTypeLock.Aborted))
                {
                    string       firstCommand = commandsTransactions.CheckCommand();
                    LockDataType LockDataType = ReturnLockType(firstCommand.Substring(0, 1));

                    FreeData freeData = ReturnFreeData(commandsTransactions.Transaction, LockDataType, commandsTransactions.WaitingData);

                    // Se o dado estiver disponivel remove todos os dados da fila e adiciona novamente à fila de execução
                    int    RemovedTransaction = 0;
                    string ciclo   = "";
                    string retorno = "";
                    switch (freeData)
                    {
                    case FreeData.FreeData:
                    case FreeData.SharedTransactionsData:
                    case FreeData.OtherSharedTransactionsData:

                        Queue <string> tempQueue = new Queue <string>();

                        // Remove tudo que está na fila de execução para adicionar a fila de espera na frente
                        while (ExecutionRow.Count > 0)
                        {
                            tempQueue.Enqueue(ExecutionRow.Dequeue());
                        }

                        while (commandsTransactions.QueueCommands.Count > 0)
                        {
                            AddOutPut("Comando: " + commandsTransactions.CheckCommand() + " adicionado à fila de execução.");
                            ExecutionRow.Enqueue(commandsTransactions.RemoveCommand());
                        }

                        // Adiciona os commandos de volta a fila de execução
                        while (tempQueue.Count > 0)
                        {
                            ExecutionRow.Enqueue(tempQueue.Dequeue());
                        }

                        commandsTransactions.Transaction.LockType = TransactionTypeLock.Executing;

                        // Adiciona à lista de excluídos para remover no final
                        excludes.Add(TransactionNumber);
                        break;

                    case FreeData.ExclusiveOtherTransactionsData:

                        // Realiza validação para analisar se a transação entrou em deadlock
                        retorno            = CheckDeadLock(TransactionNumber, commandsTransactions.WaitingData);
                        RemovedTransaction = int.Parse(retorno.Substring(0, retorno.IndexOf("|")));

                        ciclo = retorno.Substring(retorno.IndexOf("|") + 1);
                        if (RemovedTransaction > -1)
                        {
                            excludes.Add(RemovedTransaction);
                            // Desaloca dados da transação.
                            string       msg          = "";
                            Transactions Transactions = TransactionsList[RemovedTransaction];

                            // Realiza unlock do dado e retira da lista de dados utilizados.
                            string[] usedData = Transactions.ReturnDataUsed();
                            msg  = "----------- DEAD LOCK ----------- " + "\r\n";
                            msg += ciclo + "\r\n";
                            msg += "Transação " + RemovedTransaction + " eliminada, pois foi a que executou menos comandos.\r\n";
                            AddOutPut(msg);
                            foreach (var dado in usedData)
                            {
                                // Adiciona saída unclok para dados liberados
                                AddOutPut(CreateLock(LockDataType.Unlock, Transactions.TransactionNumber, dado, Transactions.ReturnDataLockType(dado)));
                                // Remove dado e transação da lista de dados locks
                                RemoveDataLocksList(Transactions, dado);
                                // Remove dado da lista de transações
                                Transactions.RemoveData(dado);
                            }
                            Transactions.LockType = TransactionTypeLock.Aborted;
                        }
                        break;
                    }
                }
            }

            foreach (var transactionNumber in excludes)
            {
                WaitingTransactionsList.Remove(transactionNumber);
            }
        }