Array
(
)

[JAVA] Problema com Threads e SQL

Matheus Ragoso
   - 23 set 2014

Estou iniciando em OO e JAVA, e estou criando um programa para atender algumas necessidades de um game.
tal programa executa por meio de threads ações como contar quantos minutos a pessoa está jogando, faz sorteio etc..
tenho o SQL.java
#Código/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package Class;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author Matheus
*/
public class SQL{

private static String url;

public boolean testConnection(String instance, String user, String pass, int port) throws ClassNotFoundException{
try {
Connection conn;
url = "jdbc:sqlserver://"+ instance + ":" + port;
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
conn = DriverManager.getConnection(url,user,pass);
conn.close();
return true;
}catch(SQLException ex){
return false;
}
}

public static Connection conectar(Configs param) throws SQLException{
try{
return DriverManager.getConnection("jdbc:sqlserver://" + param.getInstance() + ":" + param.getPort(), param.getUser(), param.getPass());
}catch(SQLException se){
throw new SQLException("Houve um erro ao conectar " + se.getMessage());
}
}

public static ArrayList<String> getOnUser(Configs config, String colum) throws SQLException{
ArrayList<String> uaux = new ArrayList();
try{
Connection conn = conectar(config);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM ClanDB.dbo.CT");

String[] retorno;
int i = 0;
while(rs.next()){
uaux.add(rs.getString(colum));
}
stmt.close();
conn.close();
return uaux;
} catch(SQLException se){
throw new SQLException("Houve um erro ao executar " + se.getMessage());

}
}

private static boolean getInserido(Configs config, User users) throws SQLException{
try{
Connection conn = conectar(config);
Statement stmt = conn.createStatement();
String query = "SELECT COUNT(*) FROM ClanDB.dbo.Minutos WHERE ChName = '" + users.getChname() + "'";
System.out.println(query);
ResultSet rs = stmt.executeQuery(query);
int resultado = 0;
while(rs.next()){
resultado = rs.getInt(1);
}
stmt.close();
conn.close();
if(resultado == 1){
return true;
} else {
return false;
}

} catch(SQLException se){
throw new SQLException("Hove um erro ao capturar registros" + se.getMessage());
}

}

public static void saveMinuto(Configs config, User user) throws SQLException{
try{
Connection conn = conectar(config);
Statement stmt = conn.createStatement();
String sql = null;
if(getInserido(config ,user)){
sql = "UPDATE ClanDB.dbo.Minutos SET Minutos = Minutos + " + user.getMinutos() +" WHERE ChName = '" + user.getChname() +"'";
} else {
sql = "INSERT INTO ClanDB.dbo.Minutos (ChName, Minutos) VALUES ('" + user.getChname() + "' , 1)";
}
System.out.println(sql);
stmt.executeQuery(sql);
stmt.close();
conn.close();
} catch(SQLException se){
throw new SQLException("Houve um erro ao salvar minutos " + se.getMessage());
}
}

}

Minutos.java
#Código/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package functions;
import Class.Configs;
import Class.SQL;
import Class.User;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Matheus
*/
public class Minutos implements Runnable{
public static boolean start = false;

@Override
public void run() {
Configs cf = new Configs();
while(start){

try {
SQL userOn = new SQL();

User users = new User();
ArrayList listaOn = userOn.getOnUser(cf, "ChName");
for(int i = 0; i < listaOn.size(); ++i){

users.setChname((String) listaOn.get(i));
//System.out.println(users.getChname());
userOn.saveMinuto(cf, users);
}
Thread.sleep(cf.getTimerMS() * 1000);
} catch (InterruptedException ex) {
Logger.getLogger(Minutos.class.getName()).log(Level.SEVERE, null, ex);
} catch (SQLException ex) {
Logger.getLogger(Minutos.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}

User.java
#Código/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package Class;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
*
* @author Matheus
*/
public class User {
private String userid;
private String chname;
private int minutos;
private int cash;

public void setUserid(ResultSet rs) throws SQLException{
userid = rs.getString("Userid");
}

public void setChname(String charName) throws SQLException{
chname = charName;
}

public String getUserid(){
return userid;
}

public String getChname(){
return chname;
}

public void addMinutos(){
minutos++;
}

public int getMinutos(){
return minutos;
}

public void addCash(int qnt){
cash += qnt;
}

public void save(){

}

}

ao executar o programa principal e clicar no botão de iniciar
instancia-se o Minutos que inicia a Thread
na tabela CT tenho dois registros para teste no qual seria duas pessoas jogando.
algo da errado com a segunda pessoa.

Citação:
SELECT COUNT(*) FROM ClanDB.dbo.Minutos WHERE ChName = 'xTheJoker'
UPDATE ClanDB.dbo.Minutos SET Minutos = Minutos + 0 WHERE ChName = 'xTheJoker'
set 23, 2014 10:22:44 PM functions.Minutos run
GRAVE: null
java.sql.SQLException: Houve um erro ao salvar minutos A instrução não retornou um conjunto de resultados.
at Class.SQL.saveMinuto(SQL.java:109)
at functions.Minutos.run(Minutos.java:38)
at java.lang.Thread.run(Thread.java:745)
SELECT COUNT(*) FROM ClanDB.dbo.Minutos WHERE ChName = 'xTheJoker'
UPDATE ClanDB.dbo.Minutos SET Minutos = Minutos + 0 WHERE ChName = 'xTheJoker'
set 23, 2014 10:22:44 PM functions.Minutos run
GRAVE: null
java.sql.SQLException: Houve um erro ao salvar minutos A instrução não retornou um conjunto de resultados.
at Class.SQL.saveMinuto(SQL.java:109)
at functions.Minutos.run(Minutos.java:38)
at java.lang.Thread.run(Thread.java:745)

Alguém têm ideia do que pode esta acontecendo?
aceito dicas também para melhoria do código.

Ronaldo Lanhellas
   - 24 set 2014

O seu método saveMinuto() está tentando executar uma query (consulta) enquanto você está passando uma alteração (insert ou update). Mude para:

#Código
public static void saveMinuto(Configs config, User user) throws SQLException{
try{
Connection conn = conectar(config);
Statement stmt = conn.createStatement();
String sql = null;
if(getInserido(config ,user)){
sql = "UPDATE ClanDB.dbo.Minutos SET Minutos = Minutos + " + user.getMinutos() +" WHERE ChName = '" + user.getChname() +"'";
} else {
sql = "INSERT INTO ClanDB.dbo.Minutos (ChName, Minutos) VALUES ('" + user.getChname() + "' , 1)";
}
System.out.println(sql);
stmt.execute(sql); ///Mudança de executeQuery() para execute()
stmt.close();
conn.close();
} catch(SQLException se){
throw new SQLException("Houve um erro ao salvar minutos " + se.getMessage());
}
}

Matheus Ragoso
   - 24 set 2014

Ahh entendi, eu não sabia direito a diferença entre execute() e executeQuery().
dei uma pesquisada aqui e rapidamente entendi o problema.

Obrigado Ronaldo!

Ronaldo Lanhellas
   - 25 set 2014


Citação:
Ahh entendi, eu não sabia direito a diferença entre execute() e executeQuery().
dei uma pesquisada aqui e rapidamente entendi o problema.

Obrigado Ronaldo!


De nada meu caro.