Validação de consultas em batch - PreparedStatement ? [RESOLVIDO]

Minha dúvida é sobre uma verificação que eu costumo realizar e gostaria de saber se estou perdendo o meu tempo fazendo isso ou não…

Costumo validar atualizações em batch, percorrendo o array de inteiros que os objetos PreparedStatement retornam ao executar processos em batch pelo método executeBatch().
Como estou usando o ORACLE, sei que se algum dos inteiros do array for diferente de -2, significa que não foi realizada a atualização daquela instrução com sucesso.
Então disparo uma exceção ou finalizo o método retornando um valor que indica que a atualização não ocorreu com sucesso (geralmente um valor boolean).
Fiz um método hipótetico resumido abaixo:

private boolean atualizarLojaCadastroCliente (   Loja novaLoja, Loja lojaAntiga, List <Cliente> clientes  ) 
     throws SQLException
{         

            //início do método omitido
            //instanciação do objeto conexao
            // ...

            PreparedStatement ps = conexao.prepareStatement ("UPDATE CADASTRO.CLIENTE SET CODLOJA = ? WHERE CODLOJA = ? AND CODCLIENTE = ?");

            for (Cliente cli : clientes) {
                 ps.setInt (1, novaLoja.getCodigo());
                 ps.setInt (2, lojaAntiga.getCodigo());
                 ps.setInt (3, cli.getCodigoCliente());
                 ps.addBatch();
            }

            int statusBatch[] = ps.executeBatch();

            //** Minha dúvida são nos trechos abaixo:
            //É necessário mesmo eu fazer essa validação???
            for (int iStatus : statusBatch) {
                if ( iStatus != -2 )
                {
                    conexao.rollback();
                    return false;
                } 
            } 
            //**

            conexao.commit();
            ps.close();
            ps = null;

            return true;

            //Estou omitindo neste exemplo todo o tratamento de erros e blocos try..catch..finally

}    //final do método

Gostaria de saber se é necessário percorrer o vetor statusBatch somente para validar as instruções que submeti?

Sempre que uma consulta SQL não é executada corretamente, é disparado um SQLException, para qualquer BD. Então, posso me basear somente se disparar uma exceção para indicar que as instruções não foram executadas corretamente?

[color=red]Estou fazendo essa validação a toa??[/color]

for (int iStatus : statusBatch) { if ( iStatus != -2 ) { conexao.rollback(); return false; } }

Pow camarada,

vc poderia usar o método ps.execute();

se o update for feito corretamente ele irá dar o commit, se não ele dá erro e non atualiza

xD

private boolean atualizarLojaCadastroCliente(Loja novaLoja,
			Loja lojaAntiga, List<Cliente> clientes) {

		try {			
			PreparedStatement ps = conexao
					.prepareStatement("UPDATE CADASTRO.CLIENTE SET CODLOJA = ? WHERE CODLOJA = ? AND CODCLIENTE = ?");

			for (Cliente cli : clientes) {
				ps.setInt(1, novaLoja.getCodigo());
				ps.setInt(2, lojaAntiga.getCodigo());
				ps.setInt(3, cli.getCodigoCliente());
                // Aqui vc executa a operação
				ps.execute();
			}
			
			ps.close();
			
			return true;
		} catch (SQLException e) {
			return false;
		}

	} // final do método

Espero ter ajudado :smiley:

[quote=f4binho]Pow camarada,

vc poderia usar o método ps.execute();

se o update for feito corretamente ele irá dar o commit, se não ele dá erro e non atualiza

xD

private boolean atualizarLojaCadastroCliente(Loja novaLoja,
			Loja lojaAntiga, List<Cliente> clientes) {

		try {			
			PreparedStatement ps = conexao
					.prepareStatement("UPDATE CADASTRO.CLIENTE SET CODLOJA = ? WHERE CODLOJA = ? AND CODCLIENTE = ?");

			for (Cliente cli : clientes) {
				ps.setInt(1, novaLoja.getCodigo());
				ps.setInt(2, lojaAntiga.getCodigo());
				ps.setInt(3, cli.getCodigoCliente());
                // Aqui vc executa a operação
				ps.execute();
			}
			
			ps.close();
			
			return true;
		} catch (SQLException e) {
			return false;
		}

	} // final do método

Espero ter ajudado :smiley: [/quote]

Então amigo, o problema é que essa solução para o meu caso é inviável.

Vou realizar atualizações na quantidade média de 20~30 milhões de instruções.
Se pra cada atualização que fizer, eu der um commit com o método execute(), eu [color=darkblue]“estou na roça”[/color]… Vou terminar de atualizar em um mês…

Na realidade, a minha pergunta diz respeito a outra coisa:

Para ter certeza que uma consulta atualizou com sucesso os registros, eu sei que posso considerar que a atualização teve sucesso se não disparar um SQLException.
Até aí beleza…
Minha dúvida é se além disso, preciso [color=darkred]“ficar com a pulga atrás da orelha”[/color] e fazer uma verificação adicional, como essa abaixo:

//É necessário mesmo eu fazer essa validação??? for (int iStatus : statusBatch) { if ( iStatus != -2 ) { conexao.rollback(); return false; } } //**

Por quê estou com essa dúvida então? Se já sei que executou com sucesso se não disparar Exception, por quê razão existe esse retorno do método?
E o X da questão que me preocupa:
Há alguma possibilidade da atualização de uma ou mais intruções em batch sair errada e não ser disparado nenhum Exception???

Alguém??

Consegui ajuda na minha dúvida: http://javafree.uol.com.br/topic-878406-Duvida-conceitual-É-necessaria-uma-validacao-das-consultas-batch-de-PreparedStatement.html.

Existem as duas formas de validação mas dependem da implementação da interface JDBC. A implementação JDBC pode suportar disparar exceções e parar o processamento como pode prosseguir o processamento e apontar o erro dentro do array.

O driver da ORACLE dispara uma exceção e pára o processamento. Dessa forma pode saber se deu errado ou não.

Para casos onde quero que salve a operação (mesmo que parcial) é necessário um tratamento diferenciado, para localizar a operação onde ocorreu a falha e seus parâmetros. Mesmo assim você deve saber como o driver se comporta. O que ele retorna e se indica com precisão qual operação falhou (ou aleatoriamente)

[quote=“diego_qmota”]Segue o que descobri na documentação: JDBC Developer?s Guide and Reference. Link: http://www.oracle.com/technology/tech/java/sqlj_jdbc/pdf/a96654.pdf
O processamento pára durante a execução e lança um java.sql.BatchUpdateException:

Dessa forma, agora sei que posso verificar a atualização somente verificando se dispara uma exceção.
Não preciso então varrer o array de inteiros retornado por executeBatch [/quote]