3
Hello, I have following problem, I have a function that searches the database and returns an object. I have a "for" function that calls this method almost 300 times, due to this amount of calls mysql is returning the following error.
Algo deu errado ao fazer uma ação envolvendo formulações. com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections"
The code is below. I have no idea what I have to do to prevent this error from occurring, since I am closing Statement, Resultset and the connection in each query. Could you help me with that? Thank you.
private Formulacao retornaFormulacaoDoItem(Item item) throws Exception {
Connection cx = br.com.projeto.Conexao.Conexao.abrir();
try {
String comando = "SELECT * FROM Formulacao WHERE fk_item = ?";
PreparedStatement ps = cx.prepareStatement(comando);
ps.setInt(1, item.getIdItem());
ResultSet rs = ps.executeQuery();
Formulacao f = new Formulacao();
ArrayList list = new ArrayList();
NutrienteDAO nutri = new NutrienteDAO();
int i = 0;
while (rs.next()) {
if (rs.getString("operador") != null) {
list.add(rs.getString("operador"));
} else if (rs.getString("fk_nutriente") != null) {
list.add(rs.getString("fk_nutriente"));
} else {
list.add(nutri.retornaUmNutriente(rs.getInt("fk_nutriente")).getQuantidade());
}
}
String[] re = new String[list.size()];
for (int j = 0; j < list.size(); j++) {
re[j] = list.get(j).toString();
}
f.setCalculo(re);
ps.close();
rs.close();
return f;
} catch (Exception e) {
throw new Exception("Algo deu errado ao retornar os dados de formula do item" + e);
} finally {
cx.close();
}
}
Connection class with seat.
import java.sql.Connection;
import java.sql.DriverManager;
/**
*
* @author jpsa
*/
public class Conexao {
private static final String USUARIO = "root";
private static final String SENHA = "123456";
private static final String URL = "jdbc:mysql://localhost:3306/miner";
private static final String DRIVER = "com.mysql.jdbc.Driver";
// Conectar ao banco
public static Connection abrir() throws Exception {
// Registrar o driver
Class.forName(DRIVER);
// Capturar a conexão
Connection conn = DriverManager.getConnection(URL, USUARIO, SENHA);
// Retorna a conexao aberta
return conn;
}
}
Add your connection class too, maybe the problem is in it.
– user28595
@Diegof Pus.
– joao paulo santos almeida
Have you tried the
ps
andrs
in the Finally block ?– DiegoAugusto
Already checked if this function is not being called in parallel (multithreads)?
– NilsonUehara
Are you making a connection per query? Normally you make the connection outside the loop, do what you have to do, and then close. Depending on the case, you can leave the connection open during the life of the application, but it depends on the scale on which it will be used.
– Bacco
Looking at this code I can’t tell for sure if you’re using connection pool. Apparently it is (otherwise even the 300 commands would be incredibly slow). The stop is as follows: in a pool, the connection is not immediately closed when it is abandoned - it is only closed after a time without use, so that your code does not close the connection when you give a close-up, but just return it to the pool. The next request comes very fast and ends up opening a new connection. Anyway, basically you’re doing it wrong.
– Caffé
You’re discovering why to manage the connection within the routine itself that reads and manipulates data is not a good practice. A good practice is to open the connection at the beginning of the main request, and use the same connection to execute all the commands of the request, in all the routines and subroutines that meet the request (unless you wanted some kind of parallelism).
– Caffé
In fact, it is not good practice or not (there is no reason for something to be called "good practice" or "bad practice" in programming, this is a stuck legend). In this case, it is really wrong, and the true reason is what Caffé explained after the good practice part :)
– Bacco
The connection was in the normal constructor method, I will only create this "Cx" connection to see if it closed the connection so, The Loop I speak of is not in the "return methodFormulacaoDoItem()" but in another class that calls this method in the loop .
– joao paulo santos almeida
This is what you said, @Bacco, a new legend, very poorly based, helping to reduce the quality of software produced by professionals who are still gaining experience. A pity... Fortunately I haven’t seen much ground for this new balelinha around.
– Caffé
@Bacco Just to not go too far, attend only to this specific example, is not wrong as you said. It’s just bad practice - after all it compiles, passes the automated test, and even works for a smaller amount of records, and could never go wrong. So it’s not necessarily wrong, but it’s necessarily bad practice, which can eventually turn out to be (as it turned out). Believing in the nonsense that "there is no good practice" is not a good practice :D
– Caffé
@Caffé is not a matter of faith, it is that in practice, everything that is called good practice or bad practice needs an explanation, so the term is just noise. And as it is a term that adds nothing of tangible information, it ends up being used absurdly more by those who have no way of explaining themselves. It turns into a crutch, and its continued use ends up reflecting a larger user problem. That my term "wrong" isn’t the best, but "bad practice" doesn’t say anything either. Better to say it’s "problematic for x, y, z," which is what you explained later, focusing on the reason for the problem,.
– Bacco
@Bacco No, my dear. Wrong. Not everything needs a good and understandable explanation immediately. Often we are not even prepared to understand the explanation in depth and heart yet, so it can be a big waste of time. If you were to expect to understand in depth all the right steps to produce good software before doing so, your first good software would come out at 60 years of career. A superficial explanation of output often advances the learning process, often until no explanation can be useful. That’s how it works in every field.
– Caffé
@Caffé is in charge of the readers to choose to follow their recommendations or mine, I think it is unnecessary to prolong the discussion here, I insist on my point with a reason that goes far beyond your person, enjoy who wants. But if you think your way is better for people, move on. My experience says no, but it also says that there is no point in arguing (until you are not exactly what I want to convince of anything, and I believe the reciprocal is true). So I am satisfied with what I said earlier.
– Bacco
Guys, about good practice let’s leave it to the machine man interface classes, and good college design practices, for now let’s focus on a database problem.
– joao paulo santos almeida
@And yet, my explanation was very superficial, and I quoted very superficially only one of the many problems that this bad practice can cause. Do you think that’s enough? Do you think I’ve gone beyond saying that it’s not "good practice"? Because I don’t think I was even close to being enough in my explanation (so much so that the AP didn’t understand, I can see by your next comment). So any superficial explanation serves? Just to avoid using the expression "good practice"? In this case, we have come to an agreement (except that I have nothing against this term).
– Caffé
@joaopaulosantosalmeida, let us chat. We are on time :D
– Caffé
@joaopaulosantosalmeida Please make a single Drivermanager.getConnection and use this same connection for the whole process, and tell us if the error goes away (and show the code, of course).
– Caffé