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.