Ir para o conteúdo

 Voltar a SGA LIVRE De...
Tela cheia

Bugs de senhas duplicadas com mais de uma triagem

20 de Novembro de 2012, 13:03 , por Desconhecido - | 1 Pessoa seguindo este artigo.
Visualizado 78 vezes

Peguei dois problemas de senhas duplicadas, quando tem mais de uma triagem.

Na primeira vez, o motivo foi um delay na rede que ao aparecer o popup de impressão as duas triagens atualizaram o janela com a mesma senha. Duas senhas distintas são geradas (funcionamento normal), porém a mesma senha (a última) é impressa duplicada.

O erro acontece porque no popup busca a última senha gerada e não a última senha gerada por aquela pessoa. Então para resolver isso coloquei para imprimir a senha da sessão (caso não tenha, pega a última):

modules/sga/triagem/acoes/imprimir_senha.php
$unidade = SGA::get_current_user()->get_unidade();
$senha = Session::getInstance()->get("ultima_senha");
/*
 * verifica se ja tem uma senha na sessao.
 * Ao pegar direto a ultima senha, estava dando problema no acesso concorrente. Mais de uma triagem gerando a senha,
 * e na hora de imprimir estavam imprimindo senhas duplicadas (a ultima)
 */
if (!$senha) {
    $senha = DB::getInstance()->get_ultima_senha($unidade->get_id());
}
TTriagem::imprime($senha, $unidade);

 

Na segunda vez, foi realmente gerado dois atendimentos com a mesma senha. No código, primeiro é feito um select e depois é feito o insert com o número da senha incrementado.

O problema é de no intervalo entre o select e insert, um outro select pode ser feito, o que resultará no bug descrito. Então temos que garantir a atomicidade da operação:

método distribui_senha
INSERT INTO atendimentos
(id_uni, id_serv, id_pri, id_stat, nm_cli, num_guiche, dt_cheg, ident_cli, num_senha)
-- select dentro do insert para garantir atomicidade
SELECT
    :id_uni, :id_serv, :id_pri, :id_stat, :nm_cli, :num_guiche, :dt_cheg, :ident_cli,
    COALESCE(
        (
            SELECT
                num_senha
            FROM
                atendimentos a
            WHERE
                a.id_uni = :id_uni
            ORDER BY
                num_senha DESC
            LIMIT 1
        ) , 0) + 1

Autor: Rogério Alencar Lino Filho


1Um comentário

  • C24406344856db5d7d7136286a254685?only path=false&size=50&d=404Rogério Alencar Lino Filho(usuário não autenticado)
    20 de Novembro de 2012, 19:17

     

    No caso do Insert atual (distribui_senha) já há uma proteção (lock), porém quando há concorrência lança uma exceção e não insere. Dessa maneira (insert com select), além de ficar mais fácil portar a query para outro banco (meu caso), garante a inserção mesmo em caso de concorrência.

Encontro da comunidade SGA Livre no FISL11

13 de Julho de 2010, 15:41, por Desconhecido

Prezados,



Em uma semana, SGA Livre ultrapassa mil usuários

10 de Novembro de 2009, 19:19, por Desconhecido

Em apenas uma semana de funcionamento, a comunidade do Sistema de Gerenciamento do Atendimento (SGA Livre) do Portal Software Público atingiu a marca de mil usuários. O lançamento e a disponibilização do software livre foi feito no último dia 22, durante a 6ª Conferência Latino-Americana de Software Livre (Latinoware 2009), que ocorreu em Foz do Iguaçu (PR).



Nova versão da aplicação Web 1.0.2

4 de Novembro de 2009, 17:05, por Desconhecido

Disponível nova versão da aplicação web (1.0.2). Corrige uma falha na impressão da senha, no módulo de Triagem.



Nova versão da aplicação Web 1.0.1

29 de Outubro de 2009, 12:56, por Desconhecido

Disponível nova versão da aplicação Web do SGA LIVRE, que corrige: