示例#1
0
        private void RemoveDataLocksList(Transactions Transactions, string Dado)
        {
            DataLockTransactions dadoLockTransactions = TransactionDataLock[Dado];

            if (dadoLockTransactions != null)
            {
                dadoLockTransactions.RemoveTransaction(Transactions);

                /* Se não existe mais nenhuma transação utilizando o dado
                 * então remove da lista de dados utilizados. */
                if (dadoLockTransactions.NumberOfTransactions().Equals(0))
                {
                    TransactionDataLock.Remove(Dado);
                }
            }
        }
示例#2
0
        private FreeData ReturnFreeData(Transactions Transactions, LockDataType LockDataType, string Dado)
        {
            // Verifica se o dado está lockado para alguma sessão
            if (TransactionDataLock.ContainsKey(Dado))
            {
                DataLockTransactions usedData = TransactionDataLock[Dado];
                // Verifica se está lockado para a transação que está tentando acessar.
                if (usedData.CheckLockForTransaction(Transactions.TransactionNumber))
                {
                    /* Se o tipo de dado for restrito deve ter lock exclusivo, neste caso
                     * não pode estar lockado para outras transações */
                    if (LockDataType.Equals(LockDataType.Exclusive) && usedData.NumberOfTransactions() > 1)
                    {
                        return(FreeData.ExclusiveOtherTransactionsData);
                    }

                    else
                    {
                        return(FreeData.SharedTransactionsData);
                    }
                }

                // Verifica se tem lock exclusivo para outra sessão.
                else
                {
                    /* Adiciona à lista de espera quando estiver lock exclusivo para outra transação
                     * Ou quando a transação pediu lock exclusivo */
                    if (usedData.LockType.Equals(LockDataType.Exclusive) || LockDataType.Equals(LockDataType.Exclusive))
                    {
                        return(FreeData.ExclusiveOtherTransactionsData);
                    }

                    else
                    {
                        return(FreeData.OtherSharedTransactionsData);
                    }
                }
            }
            // Quandoo dado não está sendo utilizado por nenhuma sessão
            else
            {
                return(FreeData.FreeData);
            }
        }
示例#3
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);
        }
示例#4
0
        public void SolvingExecutingTransactions(LockDataType LockDataType, string Dado, Transactions Transactions, string Command)
        {
            DataLockTransactions usedData;

            // Verifica se o dado está disponível
            if (LockDataType.Equals(LockDataType.Commit))
            {
                /* Quando for commit, verifica se o status da transação esta waiting.
                 * se não estiver percorre a lista de dados lockadas pela transação e libera todas e dispara o commit
                 * Se estiver Waiting adiciona o comando commit a lista de espera */
                if (Transactions.LockType.Equals(TransactionTypeLock.Waiting))
                {
                    AddCommandWaitingQueue(Transactions, Command);
                }

                // libera lock dados e realiza commit.
                else if (!Transactions.LockType.Equals(TransactionTypeLock.Aborted))
                {
                    // Realiza unlock do dado e retira da lista de dados utilizados.
                    string[] usedDataVet = Transactions.ReturnDataUsed();
                    foreach (var dado in usedDataVet)
                    {
                        // 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);
                    }
                    // Incrementa Commands executados da transação
                    Transactions.ExecutedCommands++;

                    // Adiciona saída para commit.
                    AddOutPut(Command);
                }
            }
            // Verifica disponibidade do dado para a transação e Command
            else
            {
                //DadoLockTransactions usedData;
                FreeData freeData = ReturnFreeData(Transactions, LockDataType, Dado);
                // Dado não foi lockado por nenhuma transação
                if (freeData.Equals(FreeData.FreeData))
                {
                    usedData = new DataLockTransactions(Dado, LockDataType);
                    TransactionDataLock.Add(Dado, usedData);
                    TransactionDataLock[Dado].AddTransaction(Transactions);
                    Transactions.AddData(Dado, LockDataType);
                    // Adiciona lock.
                    AddOutPut(CreateLock(LockDataType, Transactions.TransactionNumber, Dado, null));
                    // Incrementa Commands executados da transação
                    Transactions.ExecutedCommands++;
                    // Adiciona Command lido
                    AddOutPut(Command);
                }
                // Dado já esta lockado para a transação, mas como shared
                else if (freeData.Equals(FreeData.SharedTransactionsData))
                {
                    usedData = TransactionDataLock[Dado];
                    // Faz upgrade no lock se necessário.
                    if (UpgradeLock(usedData, LockDataType, Transactions))
                    {
                        AddOutPut(CreateLock(LockDataType, Transactions.TransactionNumber, Dado, null));
                    }

                    // Incrementa Commands executados da transação
                    Transactions.ExecutedCommands++;
                    // Adiciona Command lido
                    AddOutPut(Command);
                }
                // Dado está com lock shared em outra transação
                else if (freeData.Equals(FreeData.OtherSharedTransactionsData))
                {
                    // Adiciona o dado à lista de dados da transação
                    Transactions.AddData(Dado, LockDataType);
                    TransactionDataLock[Dado].AddTransaction(Transactions);
                    // Adiciona lock.
                    AddOutPut(CreateLock(LockDataType, Transactions.TransactionNumber, Dado, null));
                    // Incrementa Commands executados da transação
                    Transactions.ExecutedCommands++;
                    // Adiciona Command lido
                    AddOutPut(Command);
                }

                /* Dado está com lock exclusivo em outra transação
                 * ou precisa de lock exclusivo para a transação atual */
                else if (freeData.Equals(FreeData.ExclusiveOtherTransactionsData))
                {
                    AddCommandWaitingQueue(Transactions, Command);
                }
            }
        }