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