java - Springboot同步方法

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

我有一个需要同步运行的方法(如果 10 个用户调用此方法,第一个用户运行该方法,剩余 9 个用户完成,然后第二个用户执行该方法,剩余 8 个等待...)

所以这个方法需要在我的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 是第一个拿到号码的

最佳答案

虽然,我仍然不相信在这种情况下您需要同步,但您可以提取一个方法来获取下一个值:

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

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

关于java - Springboot同步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52406630/

相关文章:

java - 具有任意 AND 子句的动态 spring 数据 jpa 存储库查询

java - 如何将字符串打印到系统控制台?

java - Blue J,我的 listMembers 方法没有从我的数组列表中打印出正确的数据

java - NTFS 目录有 100K 个条目。如果分布在 100 个子目录中,性能会提升多少?

java Spring使用ajax上传文件

java - 为什么 Gradle 'build' 任务不是最新的,即使源代码没有变化?

spring-data-jpa - QueryDSL NoSuchMethodError : jpa. JPQLQuery.from() 错误

spring-boot - SpringBootServletInitializer 无法在 tomcat 服务器上运行

java - Spring-Boot 中的多个数据库与 mariaDB

scala - 如何在没有 ExecutionContext.global 和 IOApp 的情况下使用 cat 效果中的计时器?