Bom dia pessoal Estou com um problema que não consigo resolver Quando tenho um fluxo muito grande de pessoas retirando senhas acontece algumas duplicidades Duas senhas de mesmo numero e de horários diferentes Alguém sabe como resolver isso?
Está acontecendo comigo também. Duplicando a senha. Dai quando vou verificar no monitor, aparece apenas a primeira senha e a segunda nem aparece. Versão: v1.4
Tive esse mesmo problema em um ambiente com 9 pessoas fazendo a triagem. Para solucionar o problema, criei uma trigger no banco que verifica se a senha que está tentando inserir já existe para unidade atual. Caso exista, retorna o erro para o usuário.
Segue o script create da trigger implementada no meu ambiente:
-- Function: bloqueia_repetidos()
-- DROP FUNCTION bloqueia_repetidos();
CREATE OR REPLACE FUNCTION bloqueia_repetidos() RETURNS trigger AS $BODY$ DECLARE
BEGIN
if exists(select * from atendimentos where unidade_id = NEW.unidade_id and num_senha = NEW.num_senha and atendimento_id is null and NEW.atendimento_id is null) then raise exception 'Registro duplicado, por favor repita a operação.'; else return NEW; end if;
END; $BODY$ LANGUAGE plpgsql VOLATILE COST 100; ALTER FUNCTION bloqueia_repetidos() OWNER TO novosga;
@thyagomn qual versão que você está usando? Uso 1.4 acontece isso com uma certa frequência, vou atualizar para 1.5 mas queria saber se esse erro acontece na versão mais nova.
Na versão 2.0 estou trabalhando para acabar com esse problema. Porém, esse caso é estranho porque as senhas tem uma grande diferença de tempo, normalmente o problema de mesmo número daria para emissão simultânea das senhas.
Atualizei para a versão 1.5.1 no ultimo final de semana e atualizei o triagem touch, até o momento não ocorreu esse problema. Estou monitorando essa questão.
Galera, desculpe por não ter respondido, mas não tinha visto que já tinham me perguntado sobre isso, então é o seguinte, esse problema geralmente ocorre quando existem muitas pessoas emitindo senhas simultaneamente em uma mesma unidade.
@rogeriolino provavelmente o que está acontecendo é que os usuários da triagem coincidem de clicar no botão de emissão de senha da mesma fila com uma diferença de apenas milésimos de segundos, portanto para resolver, talvez se você executar uma verificação duplicada, quando você pegar o número da próxima senha a ser salva, antes de salvar no banco verifique se já existe uma senha como essa salva, caso exista, volte para o procedimento de buscar o próximo número e salvar (vai ficar tipo num loop infinito mesmo, se quiser aumentar o controle, especifique um limite de loops e se esse limite atingir, retorna um erro ao usuário). Assim creio que possa solucionar esse problema. Como não entendo muito desse framework (atualmente minha linguagem padrão é python usando o framework Django) infelizmente não consigo te ajudar muito na implementação da lógica mas caso precise de ajuda, entre em contato comigo que posso ver o que é possível ser feito (entendo bem de lógica, então talvez vendo o trecho do código posso ter uma idéia melhor para resolver). Mas creio que a trigger pode ser uma medida adicional de segurança que você pode implementar mesmo que tenha resolvido os problemas de inserção.
@marciome2000 não sei se já resolveu o problema mas a explicação que dei ao @rogeriolino se aplica a você, e para sanar, basta executar a função que coloquei no meu ultimo post que irá criar a função de gatilho (trigger) que será chamada toda a vez que uma senha for emitida para verificar se já existe uma senha com o mesmo número para o serviço solicitado lançada, caso não exista salva e caso contrário retorna uma mensagem para o usuário. Caso ainda tenha ficado dúvidas, pode entrar em contato que tentarei saná-las.
--- EDIT INICIO ---
Agora que percebi, quando escrevi aquele post eu estava no meio do evento e acabei escrevendo ele um pouco apressado, então ficou faltando uma coisa. Na verdade aquela função é uma procedure e não a trigger, ficou faltando criar a trigger que vai executar a função do post anterior, por isso ficou esquisito. Então depois de executar o trecho de código acima (que cria a procedure), é necessário criar a trigger, o que pode ser feito pela interface do seu gerenciador do banco (pgadmin, phppgadmin, etc) ou executar o código a seguir:
CREATE TRIGGER bloqueia_repetidos BEFORE INSERT ON atendimentos FOR EACH ROW EXECUTE PROCEDURE bloqueia_repetidos();
O código acima cria uma trigger com o nome bloqueia_repetidos que toda vez que houver um insert na tabela executará a procedure bloqueia_repetidos() que escrevi no post anterior. @marciome2000, acredito que caso tenha tentado executar o código anterior e não tenha resolvido, isso que deve ter faltado na implementação.
--- EDIT FIM ---
Desculpe o post grande, mas tentei deixar o mais claro possível. Vou tentar evitar que isso se repita, atualizei minhas configurações de notificação para evitar perder mensagens.
Caramba, vocês complicam demais, para não duplicar senhas nunca, jamais, never, basta ordenar pela ID da senha na hora de criar as senhas, para isso basta mudar o código colocar order by ID no lugar de order by numerosenha no arquivo AtendimentoService.php aonde tem sort by numerosenha.
blocos "Retorna a ultima senha do serviço" e "Retorna a ultima senha da unidad" e.numeroSenha desc troque por e.id desc
Bom dia! O NovoSGA está em uso aqui na Prefeitura desde Maio/2017 e até o momento não havia sido reportada nenhuma duplicidade. Temos 3 unidades usando o mesmo banco de dados e aqui a numeração é sequencial por unidade, com as senhas sendo zeradas automaticamente toda madrugada em rotina executada no servidor. Na 4a feira tivemos 2 episódios de duplicidade na unidade onde temos 2 pessoas fazendo triagem. Observei no banco de dados que nos 2 casos as senhas foram emitidas com 1 segundo de diferença, por atendentes diferentes. 61A emitida às 2017-11-01 10:38:45 61A emitida às 2017-11-01 10:38:44 170A emitida às 2017-11-01 15:01:04 170D emitida às 2017-11-01 15:01:03
Estou em dúvida de qual solução implantar: @thyagomn - criação de trigger e procedure no banco de dados @netdados - alteração do campo do order by no AtendimentoService.php
@rogeriolino alguma orientação especial? Qual a solução sendo adotada para a versão 2.0?
Alguém mais implantou e tem alguma sugestão a oferecer?
olha, todas as instalações que fiz, para teste ou produção eu modifico esse campo, e mesmo quando utilizado o sistema para gerar 1000 senhas sequenciais, nenhuma sai repetida.
Segui sua orientação e alterei 2 linhas do arquivo src/Novosga/Service/AtendimentoService.php para a ordenação dos dados ser 'order by ID' no lugar de 'order by numerosenha'.
Linha 702 mudei de: ->createQuery("SELECT e FROM Novosga\Model\Atendimento e JOIN e.servicoUnidade su WHERE su.unidade = :unidade ORDER BY e.numeroSenha DESC")
Para: ->createQuery("SELECT e FROM Novosga\Model\Atendimento e JOIN e.servicoUnidade su WHERE su.unidade = :unidade ORDER BY e.id DESC")
Linha 719 mudei de: ->createQuery("SELECT e FROM Novosga\Model\Atendimento e JOIN e.servicoUnidade su WHERE su.servico = :servico AND su.unidade = :unidade ORDER BY e.numeroSenha DESC")
Para: ->createQuery("SELECT e FROM Novosga\Model\Atendimento e JOIN e.servicoUnidade su WHERE su.servico = :servico AND su.unidade = :unidade ORDER BY e.id DESC")
Comments
tentei isso mas não adiantou
hoje tive um episodio com varias senhas duplicadas
uma delas repetiu 5 vezes
Duplicando a senha.
Dai quando vou verificar no monitor, aparece apenas a primeira senha e a segunda nem aparece.
Versão: v1.4
Para solucionar o problema, criei uma trigger no banco que verifica se a senha que está tentando inserir já existe para unidade atual.
Caso exista, retorna o erro para o usuário.
Segue o script create da trigger implementada no meu ambiente:
-- Function: bloqueia_repetidos()
-- DROP FUNCTION bloqueia_repetidos();
CREATE OR REPLACE FUNCTION bloqueia_repetidos()
RETURNS trigger AS
$BODY$
DECLARE
BEGIN
if exists(select * from atendimentos where unidade_id = NEW.unidade_id and num_senha = NEW.num_senha and atendimento_id is null and NEW.atendimento_id is null) then
raise exception 'Registro duplicado, por favor repita a operação.';
else
return NEW;
end if;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION bloqueia_repetidos()
OWNER TO novosga;
Poderia explicar melhor?
Não tenho muita intimidade com bancos de dados. Uso postgresql e estou com esse mesmo problema de duplicidade de senhas.
Agradeço sua atenção.
Uso 1.4 acontece isso com uma certa frequência, vou atualizar para 1.5 mas queria saber se esse erro acontece na versão mais nova.
Só temos um terminal de auto atendimento que gera as senhas. Segue foto:
http://i.imgur.com/yDQ7Ola.jpg
Estou monitorando essa questão.
@rogeriolino provavelmente o que está acontecendo é que os usuários da triagem coincidem de clicar no botão de emissão de senha da mesma fila com uma diferença de apenas milésimos de segundos, portanto para resolver, talvez se você executar uma verificação duplicada, quando você pegar o número da próxima senha a ser salva, antes de salvar no banco verifique se já existe uma senha como essa salva, caso exista, volte para o procedimento de buscar o próximo número e salvar (vai ficar tipo num loop infinito mesmo, se quiser aumentar o controle, especifique um limite de loops e se esse limite atingir, retorna um erro ao usuário). Assim creio que possa solucionar esse problema. Como não entendo muito desse framework (atualmente minha linguagem padrão é python usando o framework Django) infelizmente não consigo te ajudar muito na implementação da lógica mas caso precise de ajuda, entre em contato comigo que posso ver o que é possível ser feito (entendo bem de lógica, então talvez vendo o trecho do código posso ter uma idéia melhor para resolver). Mas creio que a trigger pode ser uma medida adicional de segurança que você pode implementar mesmo que tenha resolvido os problemas de inserção.
@marciome2000 não sei se já resolveu o problema mas a explicação que dei ao @rogeriolino se aplica a você, e para sanar, basta executar a função que coloquei no meu ultimo post que irá criar a função de gatilho (trigger) que será chamada toda a vez que uma senha for emitida para verificar se já existe uma senha com o mesmo número para o serviço solicitado lançada, caso não exista salva e caso contrário retorna uma mensagem para o usuário. Caso ainda tenha ficado dúvidas, pode entrar em contato que tentarei saná-las.
--- EDIT INICIO ---
Agora que percebi, quando escrevi aquele post eu estava no meio do evento e acabei escrevendo ele um pouco apressado, então ficou faltando uma coisa.
Na verdade aquela função é uma procedure e não a trigger, ficou faltando criar a trigger que vai executar a função do post anterior, por isso ficou esquisito. Então depois de executar o trecho de código acima (que cria a procedure), é necessário criar a trigger, o que pode ser feito pela interface do seu gerenciador do banco (pgadmin, phppgadmin, etc) ou executar o código a seguir:
CREATE TRIGGER bloqueia_repetidos
BEFORE INSERT
ON atendimentos
FOR EACH ROW
EXECUTE PROCEDURE bloqueia_repetidos();
O código acima cria uma trigger com o nome bloqueia_repetidos que toda vez que houver um insert na tabela executará a procedure bloqueia_repetidos() que escrevi no post anterior. @marciome2000, acredito que caso tenha tentado executar o código anterior e não tenha resolvido, isso que deve ter faltado na implementação.
--- EDIT FIM ---
Desculpe o post grande, mas tentei deixar o mais claro possível.
Vou tentar evitar que isso se repita, atualizei minhas configurações de notificação para evitar perder mensagens.
não queria mexer no banco e no meu caso é só uma pessoa fazendo triagem e a senha as vezes sai em duplicidade
optimize table atend_codif
optimize table atendimentos
blocos "Retorna a ultima senha do serviço" e "Retorna a ultima senha da unidad"
e.numeroSenha desc
troque por
e.id desc
obs: cuidado onde vocês mudam.
T+
O NovoSGA está em uso aqui na Prefeitura desde Maio/2017 e até o momento não havia sido reportada nenhuma duplicidade.
Temos 3 unidades usando o mesmo banco de dados e aqui a numeração é sequencial por unidade, com as senhas sendo zeradas automaticamente toda madrugada em rotina executada no servidor.
Na 4a feira tivemos 2 episódios de duplicidade na unidade onde temos 2 pessoas fazendo triagem. Observei no banco de dados que nos 2 casos as senhas foram emitidas com 1 segundo de diferença, por atendentes diferentes.
61A emitida às 2017-11-01 10:38:45
61A emitida às 2017-11-01 10:38:44
170A emitida às 2017-11-01 15:01:04
170D emitida às 2017-11-01 15:01:03
Estou em dúvida de qual solução implantar:
@thyagomn - criação de trigger e procedure no banco de dados
@netdados - alteração do campo do order by no AtendimentoService.php
@rogeriolino alguma orientação especial? Qual a solução sendo adotada para a versão 2.0?
Alguém mais implantou e tem alguma sugestão a oferecer?
Obrigada.
T+
Segui sua orientação e alterei 2 linhas do arquivo src/Novosga/Service/AtendimentoService.php para a ordenação dos dados ser 'order by ID' no lugar de 'order by numerosenha'.
No código existente no GitHub são as linhas 702 e 719
https://github.com/novosga/novosga/blob/master/src/Novosga/Service/AtendimentoService.php
Linha 702 mudei de:
->createQuery("SELECT e FROM Novosga\Model\Atendimento e JOIN e.servicoUnidade su WHERE su.unidade = :unidade ORDER BY e.numeroSenha DESC")
Para:
->createQuery("SELECT e FROM Novosga\Model\Atendimento e JOIN e.servicoUnidade su WHERE su.unidade = :unidade ORDER BY e.id DESC")
Linha 719 mudei de:
->createQuery("SELECT e FROM Novosga\Model\Atendimento e JOIN e.servicoUnidade su WHERE su.servico = :servico AND su.unidade = :unidade ORDER BY e.numeroSenha DESC")
Para:
->createQuery("SELECT e FROM Novosga\Model\Atendimento e JOIN e.servicoUnidade su WHERE su.servico = :servico AND su.unidade = :unidade ORDER BY e.id DESC")
No dia 13/11 fizemos as alterações descritas acima para colocar 'order by ID' conforme orientação do @netdados
Hoje voltamos a ter senha duplicada gerada com 1 segundo de diferença.
2017-11-28 10:34:18
2017-11-28 10:34:19
Temos 2 atendentes no balcão de triagem gerando senha.
Alguma sugestão?
Banco MySQL.
Acredito que seja mesmo um delay na obtenção do ID, pois ocorreu com uma unidade externa que tem reportado lentidão no acesso à rede (intranet).
Como temos 2 pessoas emitindo senha, às vezes ocorre de gerarem simultaneamente.
Será que a solução de criação de trigger sugerida pelo @thyagomn não será mais eficiente?
Sugestões?
Sobre esse assunto, vi que no AtendimentoService.php (verão 1.5.1), na linha 491 do método "distribuiSenha", também tem um "e.numeroSenhaServico".
Devo alterar também para "e.id" ?
Ainda não conheço o suficiente para responder... fico daqui aguardando a orientação dos especialistas e enquanto isso vou tentar aprender mais.
Obrigada.