Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ошибка result set is already closed, при одновремен выборке из разн табл БД 
:(
    Опции темы
tusenok
Дата 27.8.2010, 10:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 13.11.2008

Репутация: нет
Всего: нет



Здравствуйте! 
У меня возникла проблема, с которой я уже долго бьюсь и не могу найти решения. 

есть некоторый GUI. Есть поток, считывающий данные из таблицы SIGNALS базы данных (firebird) каждые 2 секунды. В GUI предусмотрено, чтобы по щелчкам на определенных метках открывались окна со значениями параметров, которые так же берутся из БД, но из других таблиц (для каждого параметра своя).  Когда идет работа приложения, то иногда, видимо, когда работа с результатами запросов ResultSet  из табл SIGNALS и других таблиц, возникают следущие ошибки:

LabWindow  org.firebirdsql.jdbc.FBSQLException: The resultSet is closed
Changer: getKeyVal org.firebirdsql.jdbc.FBSQLException: The resultSet is closed

Очевидно, я что-то упустила. Но никак не погу определить, в чем проблема и как ее исправить. Надеюсь на Вашу помощь

Код

package threads;  // поток, считывающий значения из SIGNALS

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import db.DataBaseConnector;
import global_var.Global_thread;

public class ChangerTestNew extends Thread{
    
    public ChangerTestNew(){
        super("Changer");
        this.setDaemon(true);
        this.start();
    }
    
    public void run(){
        long lastCheckSign = System.currentTimeMillis()-2000;
    
        while (Global_thread.isChangerWork()){
                
           if (System.currentTimeMillis() - lastCheckSign > 2000){
              getKeyValues();
            lastCheckSign = System.currentTimeMillis();
         }
          
           synchronized(this){
                try {
                    this.wait(2000);
                } catch (InterruptedException e) {/**/}
            }
        }//while
    }
    

    private  void getKeyValues() {
        ResultSet rs = null;
        int[] arr_int = new int[14];
        Connection conn = null;
        
        try {
            conn = DataBaseConnector.getInstance().getReadConnection();
        } catch (SQLException e) {
            System.out.println("getValuesBySQL getRconnection");
        }

        if ((conn!=null)){
            
            rs = this.getValuesBySQL("select *  from SIGNALS"+
                    " where (date_time = (select max(date_time) from  SIGNALS))",conn);
            try {
                if (rs!=null){
                    if (rs.next()){
                        if (rs.isBeforeFirst())    rs.next();
                        
                        arr_int[0] = rs.getInt("LD1_S1");
                        arr_int[1] = rs.getInt("LD_S2");
                        arr_int[2] = rs.getInt("LD2_S3");
                        arr_int[3] = rs.getInt("SHPTA1_S4");
                        arr_int[4] = rs.getInt("OUS_S5");
                        arr_int[5] = rs.getInt("GRSH1_S6");
                        arr_int[6] = rs.getInt("GRSH2_S7");
                        arr_int[7] = rs.getInt("SHPTA2_S8");
                        arr_int[8] = rs.getInt("DIS_ON");
                        arr_int[9] = rs.getInt("DIS_OFF");
                        arr_int[10] = rs.getInt("DIS_ERR");
                        arr_int[11] = rs.getInt("MODE");
                        arr_int[12] = rs.getInt("DUN1");
                        arr_int[13] = rs.getInt("DUN2");
                        
                    }
                    rs.close();
                    conn.close();
                }
            } catch (SQLException e) {
                System.out.println("Changer:getKeyVal "+e);
            }
        }
    }
    
    
        
    
    private ResultSet getValuesBySQL(String SQL, Connection rConn){
        ResultSet rs = null;
        Statement st = null;
                
        if (rConn!=null)
            try{
                    st = rConn.createStatement();
                    rs = st.executeQuery(SQL);
            } catch (SQLException ex){
                System.out.println("Changer:getValuesBySQL "+ex);
            }
            
        return rs;
    }    
    
    
}


Код

package windows; // окно с данными из других таблиц

import java.awt.*;
import java.sql.*;
import java.util.*;
import javax.swing.*;
import table.*;
import subfunctions.ForGUI;
import db.*;

public class LabWindow extends JDialog
{
    private String tableName = ""; //название таблицы БД, из которой берем данные 
    private String[] headers = {"Дата","Время","Значение"};
    private int[] sizes = {90,90,90};
    private JTable tbl;
    private DBTableModelLab dbtm;
    private int countNum;
    
    String _title = "";
    public LabWindow(String title,String table_name,int cNum) throws SQLException
    {
        super(MainWindow.getMainWindow(),title,false);
        
        tableName = table_name;
        countNum = cNum;
        if (Toolkit.getDefaultToolkit().getScreenSize().height==1024)  
            ForGUI.InitWindow(this, 290,600);
        else    ForGUI.InitWindow(this, 290,500);
        _title = title;
        initTable();
        JScrollPane scr_pane = new JScrollPane(tbl);
        scr_pane.setMinimumSize(new Dimension(288,580));
        this.getContentPane().add(scr_pane);
    
    }
    

    private void initTable(){
        Connection conn = null;
        PreparedStatement pst = null;
    
        try{
            conn = DataBaseConnector.getInstance().getReadConnection();
        } catch (SQLException ex){
            System.out.println("Не уд пол соед с бд"+ex);
            return;
        }
        tbl = new JTable(); 
    //----------------------раскрашиваем строки---------------------------------
        tbl.setDefaultRenderer(Object.class, new RowRenderer());
        tbl.setDefaultRenderer(Integer.class, new RowRenderer());
        tbl.setDefaultRenderer(Timestamp.class, new RowRenderer());
        tbl.setDefaultRenderer(String.class,new RowRenderer());
    //--------------------------------------------------------------------------------
        tbl.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        tbl.setRowSelectionAllowed(false);
        tbl.setCellSelectionEnabled(true);
        tbl.getTableHeader().setReorderingAllowed(false);//запрет перетаскивания столбцов
    //--------------------------------------------------------------------------
    
    //таблица заполняется из табл БД tableName, заголовки таблицы - массив tblTitles
        dbtm = new DBTableModelLab(false, headers);
        
        Calendar cl = Calendar.getInstance(); 
        cl.add(Calendar.DAY_OF_YEAR,-1);
        java.sql.Timestamp d = new Timestamp(cl.getTimeInMillis()); //предыдущие сутки в это же время
        
        ResultSet rs = null;
        

        if (conn!=null)
            try{
                    pst = conn.prepareStatement("select DATE_TIME, VAL from " +
                                    tableName+" where DATE_TIME>'"+d+"' order by DATE_TIME");
                    rs = pst.executeQuery();
            } catch (SQLException ex){
                System.out.println("LabWin: "+ex);
            }
        
        
        try {
            dbtm.setDataSource(rs);
        } catch (Exception e) {
            System.out.println("setDataSource "+_title+" "+e);
        }
    
        tbl.setModel(dbtm);
            
        try{
            if (rs!=null) rs.close();
            conn.close();
        } catch (SQLException ex){
            System.out.println(ex);
        }
    }
    
    public ResultSet getValuesBySQL(String SQL, Connection rConn, PreparedStatement pst){
        ResultSet rs = null;
        try{
            rs = rConn.createStatement().executeQuery(SQL);
        } catch (SQLException ex){
            System.out.println("LabWin:getValBySQL "+_title+" "+ex);
        }
        
        return rs;
    }
}



Код

//DataBaseConnector
package db;

import java.io.FileInputStream;
import java.io.IOException;

import java.sql.*;
import java.util.*;

import javax.swing.JOptionPane;

public class DataBaseConnector {
    
    DBConnectionPool dbPool;
    private static DataBaseConnector instance;
    private static Properties prp = new Properties();;
    public static int[] BytesArrayPosition;
    
    static{
        try{ //инициализация prp
            prp.load(new FileInputStream("connectdb.prop"));
        }catch(IOException ioe){
            JOptionPane.showMessageDialog(null, ioe);
        }
    }

    static { //инициализация instance
        instance = new DataBaseConnector();
    }
    
    public static class DBInfo{ //объект, содержащий инф о соединении
        public String driver, user, password, cpage, url;        
    }
    
    public static DataBaseConnector getInstance() {
        return instance;
    }
    
    public static void fillDBInfo(DataBaseConnector.DBInfo dbInfo){//заполняем объект DBInfo инф-ей о БД        
        dbInfo.cpage = prp.getProperty("DB.codepage");//кодировка
        dbInfo.driver = prp.getProperty("DB.driver");//org.firebirdsql.jdbc.FBDriver
        dbInfo.password = prp.getProperty("DB.password");
        dbInfo.url = prp.getProperty("DB.url");//jdbc:firebirdsql:localhost:/ASEC/asec.gdb
        dbInfo.user = prp.getProperty("DB.user");
    }
    
    DataBaseConnector(){
        DataBaseConnector.DBInfo a = new DataBaseConnector.DBInfo();
        fillDBInfo(a);
        dbPool = new DBConnectionPool(a.driver, a.url, a.user, a.password, a.cpage);
    }

    public Connection getReadConnection() throws SQLException{
        return dbPool.getReadConnection();
    }
    
    public Connection getWriteConnection() throws SQLException{
        return dbPool.getWriteConnection();
    }
    
    public void commitTransaction() throws SQLException {
        dbPool.getWriteConnection().commit();
    }
    public void roolbackTransaction() throws SQLException {
        dbPool.getWriteConnection().rollback();
    }

}


Код


//DBConenctionPool

package db;

import java.sql.*;
import java.util.*;
import org.firebirdsql.jdbc.FirebirdConnection;

   public class DBConnectionPool  {
   private final String driver, url, user, pwd, codepage;

   private boolean driverLoaded = false;
   private Connection connR = null,
                      connW = null;

   public DBConnectionPool(String driver, String url, 
                           String user, String pwd, String codepage) {
      this.driver = driver;
      this.url    = url;
      this.user   = user;
      this.pwd    = pwd;
      this.codepage = codepage;
   }
   
   public Connection getReadConnection() throws SQLException{

     try {
         if (connR != null && !connR.isClosed()) return connR;
         
         if(!driverLoaded) {
            Class.forName(driver);//загружаем и регистрируем драйвер, экземпляр драйвера создается неявно
            driverLoaded = true;
         }
         
         Properties connInfo = new Properties();
         connInfo.put("user", user);
         connInfo.put("password", pwd);
         connInfo.put("lc_ctype", codepage);        
             
         connR = DriverManager.getConnection(url, connInfo); //создание нового соединения
         FirebirdConnection con = (FirebirdConnection)connR;
         con.setAutoCommit(true);
         con.setReadOnly(true);
         con.setTransactionIsolation(FirebirdConnection.TRANSACTION_SERIALIZABLE);
         connR = con; 
         
      }
      catch(Exception ex) {         
         connR=null;
         throw new SQLException(ex.getClass().getName() + ": " + ex.getMessage());
      }
      return connR;
   }
   
   public Connection getWriteConnection() throws SQLException{      
     if (connW != null && !connW.isClosed()) return connW;
     try{
         if(!driverLoaded) {
              Class.forName(driver); //ПРОБЛЕМА!!!!
              driverLoaded = true;
          }
         }catch(ClassNotFoundException cnf){
          throw new SQLException(cnf.getClass().getName() + ": " + cnf.getMessage());
         }
     Properties connInfo = new Properties();
     connInfo.put("user", user);
     connInfo.put("password", pwd);
     connInfo.put("lc_ctype", codepage);        
         
     connW = DriverManager.getConnection(url, connInfo);
     connW.setAutoCommit(false);    
     
     FirebirdConnection con = (FirebirdConnection)connW;
      
      return connW;
   }
   
   private void releaseConnection(Connection con) {
       try {
           if (con == connR) {
               connR.close();
               connR = null;
           } if (con == connW) {
            connW.commit();
               connW.close();
               connW = null;
           } else con.close();
       } catch (SQLException sex) {
           return;
       }     
   }
   
   private void releaseAllConnections() {
       if (connR!=null) releaseConnection(connR);
       if (connW!=null) releaseConnection(connW);
   }
   
}




PM MAIL   Вверх
ivanovpv
Дата 27.8.2010, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Варвар
**


Профиль
Группа: Участник
Сообщений: 639
Регистрация: 26.1.2005
Где: Москва

Репутация: 4
Всего: 28



Объявите getKeyValues() как synchronized


--------------------
Aut viam inveniam aut faciam
PM MAIL Skype   Вверх
tusenok
Дата 30.8.2010, 09:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 13.11.2008

Репутация: нет
Всего: нет



К сожалению ничего не получилось. getKeyValues теперь объявлена как synchronized, в LabWindow в блок  
       
Код

   try {
            dbtm.setDataSource(rs);
        } catch (Exception e) {
            System.out.println("setDataSource "+_title+" "+e);
        }
 добавлено 
Код

   try {
            synchronized(dbtm){
                  dbtm.setDataSource(rs);
           }
        } catch (Exception e) {
            System.out.println("setDataSource "+_title+" "+e);
        }

но вышеупомянутая ошибка все равно возникает (((


PM MAIL   Вверх
pathfinder
Дата 30.8.2010, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 120
Регистрация: 3.3.2010

Репутация: 2
Всего: 10



Проблема в том, что вы используете одни connR между множеством потоков ...
Код

public class DBConnectionPool  {
   private final String driver, url, user, pwd, codepage;
   private boolean driverLoaded = false;
   private Connection connR = null, // ОДИН РАЗДЕЛЯЕМЫЙ КОННЕКТ
                      connW = null;


... и в каждом потоке в конце работы закрываете коннект ...
Код

private  void getKeyValues() {
        /* skip */
                    rs.close();
                    conn.close(); // ЗАКРЫТИЕ connR
        /* skip */
    }


... естественно что при закрытии коннекта закрываются и все ассоциированные с ним ResultSet-ы.

При работе с FireBird не рекомендуется использовать один коннект из множества потоков(на форуме SQL.RU, в разделе Firebird множество раз всплывают вопросы про многопоточность и работу с коннектом).

Вместо самописного пула коннектов(который в вашем случае реализован не корректно) лучше использовать готовый(c драйвером Jaybird идут примеры, в одном из которых как раз таки есть использование пула коннектов)
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1468 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.