我有一个需要同步运行的方法(如果10个用户调用此方法,则第一个运行该方法,他完成剩余的9个等待,然后第二个执行该方法,剩下的8个等待...)< / p>
因此,此方法需要在我的PostgreSQL中保存一个寄存器,但是我需要开始并在此方法内提交事务,因此在互联网上搜索后,我找到了以下解决方案:
@org.springframework.transaction.annotation.Transactional(isolation = Isolation.SERIALIZABLE, propagation = Propagation.REQUIRES_NEW)
private synchronized Registro gerarRegistro(Protocolo protocolo, List<ServicoCalculado> servicos,String especialidade, LocalDateTime dtRegistro) throws Exception{
Registro novoRegistro = new Registro();
//this method executes one method in my service that call a method in my repository with this query -> @Query(value = "SELECT MAX(numero_registro) FROM rtdpj.registro WHERE tp_especialidade = ?1", nativeQuery = true)
Long ultimoRegistro = this.registroService.findLastRegistro(especialidade);
ultimoRegistro++;
novoRegistro.setEspecialidade(especialidade);
novoRegistro.setNrPastaPj(protocolo.getPastaPJ());
novoRegistro.setNumeroRegistro(ultimoRegistro);
novoRegistro.setRegistro(registroService.gerarRegistro(ultimoRegistro, novoRegistro.getDataRegistro()));
novoRegistro.setProtocolo(protocolo.getId());
novoRegistro.setRegistroReferencia(protocolo.getRegistroReferencia());
novoRegistro.setObjetos(protocolo.getObjetos());
novoRegistro.setSituacaoAtual(protocolo.getSituacaoAtualRegistro());
novoRegistro.setObservacao(protocolo.getObservacaoRegistro());
novoRegistro.setServicos(servicos);
novoRegistro.setProtocoloCancelamentoIndisponibilidade(protocolo.getProtocoloCancelamentoIndisponibilidade());
novoRegistro.setProtocoloIndisponibilidade(protocolo.getProtocoloIndisponibilidade());
novoRegistro.setNatureza(protocolo.getNatureza());
novoRegistro.setCliente(protocolo.getCliente());
novoRegistro.setIcGuardaConservacao(protocolo.getIcGuardaConservacao());
novoRegistro.setIcPossuiSigiloLegal(protocolo.getIcPossuiSigiloLegal());
novoRegistro.setNumeroRegistroReferencia(protocolo.getNumeroRegistroReferencia());
return this.registroService.save(novoRegistro);
}
这是最好的方法吗?还是有更好的方法?
在我的域中,属性 novoRegistro.setNumeroRegistro 必须是连续的,没有跳转,因此,如果我使用SERIAL,并且在保存寄存器的那一刻发生了某些事情,那么我将失去nextval,因此我必须保持客户从FIRST到IN的到达订单是第一个获得号码的
答案 0 :(得分:1)
尽管,我仍然不确定在这种情况下是否需要同步,您可以提取一个方法来获取下一个值:
private synchronized long getNextVal(...){
return ultimoRegistro++;
}
我建议使用DB提供的序列生成器(可能是创建序列表),而不要使用您遵循的方法。您的情况:sequence-generator