Springboot同步方法

时间:2018-09-19 13:08:45

标签: java spring-boot spring-data-jpa synchronized

我有一个需要同步运行的方法(如果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的到达订单是第一个获得号码的

1 个答案:

答案 0 :(得分:1)

尽管,我仍然不确定在这种情况下是否需要同步,您可以提取一个方法来获取下一个值:

private synchronized long getNextVal(...){     
  return ultimoRegistro++;
}

我建议使用DB提供的序列生成器(可能是创建序列表),而不要使用您遵循的方法。您的情况:sequence-generator