1
resposta

Controle de transação Spring Boot JPA

@Service
public class TesteServiceImpl implements TesteService {

    @Autowired
    private MesaRepository mesaRepository;

    @Override
    @Transactional
    public void teste() {
        // Comanda nome = Comanda 14
        Comanda comanda = mesaRepository.carregaPorId(1L);
        comanda.setNome("Comanda 26");
        mesaRepository.save(comanda);
        try {
            Thread.sleep(20000);
        } catch (InterruptedException ex) {
            Logger.getLogger(TesteServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    @Transactional
    public void teste1() {
        Comanda comanda = mesaRepository.carregaPorId(1l);
        System.out.println("== Comanda: " + comanda.getNome());
        // print == Comanda: Comanda 14        
    }

}

Meu controller

   @GetMapping("/teste")
    public String teste() {
        testeService.teste();
        return "teste";
    }

    @GetMapping("/teste1")
    public String teste1() {
        testeService.teste1();
        return "teste1";
    }

Quando eu chamo o teste e logo em seguida o teste 1, o valor lido por teste1 não é atualizado conforme método teste. O valor só atualiza após a thread terminar e fazer o commit. Como faço para ler esse valor antes de o commit ser realizado?

1 resposta

Olá, Marco, tudo bem com você?

Peço desculpas pela demora no retorno a sua mensagem.

No método teste(), você está atualizando o valor da propriedade nome do objeto comanda e salvando-o no repositório mesaRepository. No entanto, no método teste1(), quando você lê o valor da propriedade nome do objeto comanda, ele ainda não reflete a atualização feita no método teste(). Isso acontece porque a transação só é confirmada e o commit é realizado após a execução completa do método teste(). Portanto, o método teste1() não consegue ler o valor atualizado antes do commit.

Uma possível solução para garantir que o método teste1() leia o valor atualizado antes do commit é utilizar a anotação @Transactional(propagation = Propagation.REQUIRES_NEW) nesse método. Ao fazer isso, o método será executado em uma nova transação separada, permitindo que ele leia o valor atualizado antes do commit. Essa abordagem pode ser útil em situações em que você precisa ler valores atualizados imediatamente após uma modificação ter sido feita, mesmo antes do término da transação original. Dessa forma, você evita problemas de consistência nos dados.

Espero que essa dica te ajude a resolver o problema.

Abraços e bons estudos!