Menu

unable to release db file after close connection

Help
ke wang
2015-04-27
2015-04-29
  • ke wang

    ke wang - 2015-04-27

    I have a program running some db modification stuff. I have multiple threads, each one connect to a different db. In each of these threads, when there is exception happened, I want to delete the db file the thread is modifying. I try to add these code in the catch clause. But even I call conn.close() and set singleconnection = true. The file still can't be release at once, after about 2 minutes, it can be released.

    My code is like this:
    public class WorkerThread implements Runnable{
    ...

    public void run() {
                ...
    
        try {
            for(File file : files){
                                        ...
                    handler = (FormHandler) constructor.newInstance(env);
    
                    handler.init(file);
                    handler.handle();
                    handler.cleanUp();// call conn.close()
                }
            }
    
                        ...
    
        } catch(RuntimeException | SAXException | IOException | MessagingException | ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e)
        {
            try {
                handler.cleanUp();
            } catch (IOException e2) {
                // TODO Auto-generated catch block
                e2.printStackTrace();
            }
                        //delete db file.
    
        }
    }
    

    In the constructor of (FormHandler)handler, a connection to a db is create(each thread connect to different db):

    class Form4Handler{
    public Form4Handler(HHREnvironment env) {

        gmDao = new GestMeaningDAO();
        File db = new File(parent + language + "_godanddeaf.mdb");
        gmDao.useDB(db.getAbsolutePath());
    }
    

    }

    class GestMeaningDao{
    public void useDB(String name){
    try {
    conn = new UCanAcessDBManager(name).getConnection();
    } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }

    public class UCanAcessDBManager {

       public UCanAcessDBManager(String name){
        this.dbUrl = DB_URL_ROOT + name;
        Properties p = new Properties();
        p.put("user", USER);
        p.put("password", PASS);
        p.put("ingleconnection", true);
        // System.out.println(dbUrl);
        try {
            Class.forName(JDBC_DRIVER);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            // e.printStackTrace();
        }
        try {
            connection = DriverManager.getConnection(this.dbUrl, p);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    
       public Connection getConnection() throws SQLException{
           return connection; 
       }
    

    }

    Some one can give me some help on this problem? The same problem won't happen if there is no exception in the program. Thanks.

     

    Last edit: ke wang 2015-04-27
  • Marco Amadei

    Marco Amadei - 2015-04-27

    Hi Ke Wang, you're welcome,
    and thank you for the accurate problem description. You aren't using a connection pool.
    Firstly, may you re-try with the correct singleconnection parameter setting?

    p.put("singleconnection", "true");
    and not
    p.put("ingleconnection", true);

    And please, let me know your findings.

     

    Last edit: Marco Amadei 2015-04-28
  • ke wang

    ke wang - 2015-04-27

    Hi Amadei,
    Oh, no I didn't use thread pool. What I really use is a thread pool. The typo is a big mistake. I can't believe myself! Hope That's the cause of all these mysteries. I will try it again and let you know what happened. Thank you very much.

     
  • ke wang

    ke wang - 2015-04-28

    Hi Amadei,
    I try to fix the typo, but the same problem still happened. The program has to wait for about 2 minutes after called conn.close to delete the db file.

     
  • Marco Amadei

    Marco Amadei - 2015-04-28

    So sorry, I didn't see another mistake or misunderstanding in your code.
    If you pass a Properties to the DriverManager, you should use it as a Properties, not as an Hashtable. So both key and value in each entry should be a string even if the compiler allows the use of the put method from the base class Hashtable.
    In this case
    p.put("singleconnection", true); you put a Boolean instead and the driver can't understand, because a string is expected.
    This solves your issue:
    p.put("singleconnection", "true");
    or (better)
    p.setProperty("singleconnection", "true");

     

    Last edit: Marco Amadei 2015-04-28
  • ke wang

    ke wang - 2015-04-28

    Oh, I didn't notice the difference because I am a java noob. I will try to change that to see if things getting better. Thanks.

     
  • ke wang

    ke wang - 2015-04-29

    Hi Amadei,
    I change the true to string type. Then it works fine! This is truly great. Thanks for you help.

     

Log in to post a comment.