Olá :D
O meu programa faz o seguinte: Faz um select num banco de dados externo, pega uns dados e logo depois faz um update no banco local e outro update no banco externo. Vendo o código da pra entender melhor:
public synchronized void sincronizarAcumulados(List<Acumulado> acumulados) throws Exception {
ResultSet rs = null;
Connection conexao = null;
PreparedStatement ps = null;
try {
conexao = ConnectionFactory.getConexaoExterna();
for (Acumulado acumulado : acumulados) {
//só entra se o valor que tem pra sincronizar for maior que zero
if (acumulado.getToSync().compareTo(BigDecimal.ZERO) == 1) {
ps = conexao.prepareStatement("SELECT base, teto, valor FROM acumulados WHERE id_loja = ? LIMIT 1");
ps.setInt(1, Main.casa.getId());
ps.execute();
rs = ps.getResultSet();
while (rs.next()) {
double base = rs.getDouble(1);
double teto = rs.getDouble(2);
double valor = rs.getDouble(3);
acumulado.setBase(new BigDecimal(base));
acumulado.setTeto(new BigDecimal(teto));
acumulado.setValor(new BigDecimal(valor).add(acumulado.getToSync())); //adiciona o valor que tem que ser sincronizado
atualizar(acumulado);
}
}
}
} catch (Exception e) {
throw new Exception("Erro ao tentar sincronizar os acumulados", e);
} finally {
ConnectionFactory.closeConnection(conexao, ps, rs);
}
}
private void atualizar(Acumulado acumulado) {
PreparedStatement psLocal = null;
PreparedStatement psExterno = null;
Connection conexaoLocal = null;
Connection conexaoExterna = null;
Savepoint saveLocal = null;
Savepoint saveExterno = null;
try {
conexaoLocal = ConnectionFactory.getConexaoLocal();
conexaoExterna = ConnectionFactory.getConexaoExterna();
conexaoLocal.setAutoCommit(false);
conexaoExterna.setAutoCommit(false);
saveLocal = conexaoLocal.setSavepoint();
saveExterno = conexaoExterna.setSavepoint();
//UPDATE EXTERNO
psExterno = conexaoExterna.prepareStatement("UPDATE acumulados SET valor=? WHERE id_loja=?",
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
psExterno.setDouble(1, acumulado.getValor().doubleValue());
psExterno.setInt(2, Main.config.getIdLoja());
psExterno.executeUpdate();
//UPDATE LOCAL
psLocal = conexaoLocal.prepareStatement("UPDATE acumulado SET base=?, teto=?, valor=?, to_sync=(IF(to_sync>0,to_sync-?,0));",
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
psLocal.setDouble(1, acumulado.getBase().doubleValue());
psLocal.setDouble(2, acumulado.getTeto().doubleValue());
psLocal.setDouble(3, acumulado.getValor().doubleValue());
psLocal.setDouble(4, acumulado.getToSync().doubleValue());
psLocal.executeUpdate();
conexaoExterna.commit();
conexaoLocal.commit();
} catch (Exception e) {
Config.logger.error("Erro ao fazer atualizacao do acumulado. Tentando novamente...", e);
try {
if (saveLocal != null) {
conexaoLocal.rollback(saveLocal);
}
if (saveExterno != null) {
conexaoExterna.rollback(saveExterno);
}
} catch (SQLException ex) {
Config.logger.error("Erro ao fazer rollback da atualizacao de acumulados", ex);
}
atualizar(acumulado);
} finally {
ConnectionFactory.closeConnection(conexaoLocal, conexaoExterna, psLocal);
}
}
O código acima roda tranquilamente. O problema é quando a internet cai enquando esta sendo feito o processo. O programa fica parado por muito tempo (de 15 a 30 min depois que a internet voltou). Logo depois do tempo da uma exception e volta a rodar. A exception é:
CommunicationsException: Communications link failure
The last packet successfully received from the server was 1,011,822 milliseconds ago. The last packet sent successfully to the server was 1,010,609 milliseconds ago.
Agradeço a ajuda.