Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Dúvida sobre o funcionamento do rollback

Quando utilizamos o seguinte código:

con.setAutoCommit(false);

try {
            PreparedStatement stm = con.prepareStatement("INSERT INTO PRODUTO (nome, descricao) VALUES (?, ?)", Statement.RETURN_GENERATED_KEYS);
            adicionarVariavel("Mouse", "Mouse sem fio", stm);
            adicionarVariavel("Radio", "Radio sem pilhas", stm);

            con.commit();

            stm.close();
            con.close();
        }catch (Exception e) {
            e.printStackTrace();
            System.out.println("Rollback executado");
            con.rollback();
        }

    }

private static void adicionarVariavel(String nome, String descricao, PreparedStatement stm) throws SQLException {
    stm.setString(1, nome);
    stm.setString(2, descricao);

    if(nome.equals("Radio")) {
        throw new RuntimeException("Não foi possivel adicionar o produto");
    }

    stm.execute();

    ResultSet rst = stm.getGeneratedKeys();
    while(rst.next()) {
        Integer id = rst.getInt(1);
        System.out.println("ID: " + id);
    }
}

Ele naturalmente jogará uma excessão dentro e realizará o rollback, não adicionando os elementos dentro da tabela. Porém na impressão do ID reparei que se executar uma vez o código e ele retornar ID: 40 (exemplo) porém esse id não consta no BD (até ai ok), mas ao executar o código novamente ele tenta inserir na tabela um elemento com ID:41, não deveria ser 40 novamente?

1 resposta
solução!

Gustavo, bom dia. Este é um comportamento do banco de dados. Como estamos usando transação, o banco só commita, ou seja, confirma a operação, se todas as operações dentro da transação forem executadas com sucesso. Porém, isso não significa que as operações não são executadas no momento, o que isso significa? Pegando o nosso exemplo anterior, nós temos duas informações a serem salvas no banco de dados. A primeira execução não ocasiona a exceção, então ela é inserida no banco de dados (mas ainda não está commitada), a segunda operação ocasiona a exceção e consequentemente da o rollback na primeira operação. Como a primeira informação estava salva, mesmo que temporariamente, o banco de dados já tinha usado aquele ID pra ela, motivado pela estratégia do auto increment, logo, quando vier uma nova informação a ser salva, vai acontecer um novo incremento e o ID será o próximo, mesmo que tenha ocorrido o rollback anteriormente.