我现在有一个java application,命令行下运行的,需要连续运行几个月的时间。大概的程序流程就是使用socket接收和发送数据,现在都是用jdbc方式获得connection并使用的。我的问题是担心在运行一段时间后,这个connection会被数据库关闭掉有没有办法维持一个connection一直保持可用状态呢?这个系统只有这一个connection,不必担心多用户的问题。

解决方案 »

  1.   

    这个好说啊,把这个connection做成静态的,写个方法,其他地方请求连接时都调用这个方法,这个方法判断connection是否为空,为空就重新构建一个连接,不为空就返回
      

  2.   

    如果你的connection是数据库的connection。那你的设计问题可就大了。多用户的时候你是必须考虑线程同步的问题~~
    对于你这句话我没有理解。你的前一句话也似乎也在说你的连接方式是socket的长连接。这个连接的地址是从数据库中获得并去连接的意思吗?一般的连接最好还是以池的方式体现出来。既然你的系统中存在多用户的状况,对于每个用户从系统的角度来说都应该是并行的。
      

  3.   

    to pizzame :长连接是我与socket server的连接方式,数据库的连接是jdbc,我问的问题是关于数据库连接的我的系统只有一个用户,就是说的这个。我是用java 直接运行class文件的,这样也能用连接池吗?
      

  4.   

    我是用java 直接运行class文件的,这样也能用连接池吗?
    可以啊.
    连接池不一定是写在配置文件里的啊.
    你可以自己实现 Connection 接口 重写里面的 close() 方法
     然后 定义一个集合 来做一个简单的连接池
      

  5.   

    这些都是数据库连接池考虑的问题,如果像楼上所说的调用 close() 方法,
    并不关闭连接,需要采用 JDK 的动态代理重写 close() 方法。如果是担心长时间连接断掉的问题,那就复杂了。要采用一个线程来监视这个
    Connection,当它被数据库强行断开了,就马上重连,呵呵,说说很简单,
    实现是相当复杂的。建议楼主不要考虑自己实现了,要考虑的问题很多很多。用一个字概括就是:难可以考虑使用开源的数据库连接池,比如:C3P0、DBCP 等。如果只需要一个
    连接配置成一个就可以了,既方便又好使,为什么不用呢?
      

  6.   

    我是用java 直接运行class文件的,这样也能用连接池吗?可以把连接池配置在 ConnectionFactory 类中,使用时采用Connection con = ConnectionFactory.getConnection();其他的与 JDBC 方式相同,照样 con.close(); 掉下面是 C3P0 ConnectionFactory 的参考:import java.beans.PropertyVetoException;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.logging.Level;
    import java.util.logging.Logger;import com.mchange.v2.c3p0.ComboPooledDataSource;/**
     * C3P0连接池
     */
    public class ConnectionFactory {    private ConnectionFactory(){
        }        private static ComboPooledDataSource ds = null;    static {
            try {
                // 如果不想出现 C3P0 的日志信息,把注释去掉就行了
                // Logger log = Logger.getLogger("com.mchange");
                // log.setLevel(Level.WARNING);
                ds = new ComboPooledDataSource();
                ds.setDriverClass("com.mysql.jdbc.Driver");
                ds.setJdbcUrl("jdbc:mysql://localhost:3306/test");
                ds.setUser("root");
                ds.setPassword("root");
                ds.setMaxPoolSize(1);  // 设置最大的连接数量
                ds.setMinPoolSize(1);  // 设置最小的连接数量
            } catch (PropertyVetoException e) {
                e.printStackTrace();
            }
        }
      
        public static Connection getConnection() {
            Connection con = null;
            try {
                con = ds.getConnection();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            return con;
        }
        // C3P0 end
    }
      

  7.   

    连接池并不一定要挂在应用服务器上的,也不是只有 Web 程序能用的。
    一个简单的 main 方法就可以用了。
      

  8.   

    楼上的兄弟,可否把这个包里代码铁出来看看啊。
    import com.mchange.v2.c3p0.ComboPooledDataSource;
      

  9.   

    此回复为自动发出,仅用于显示而已,并无任何其他特殊作用
    楼主【slam21】截止到2008-06-28 09:57:53的历史汇总数据(不包括此帖):
    发帖数:17                 发帖分:375                
    结贴数:12                 结贴分:355                
    未结数:5                  未结分:20                 
    结贴率:70.59 %            结分率:94.67 %            
    楼主加油
      

  10.   

    呵呵,绝对不是多余,因为我做了类似的事情,那些Connection长时间不用,对象本身还在,但是到数据库的实际连接被DBMS cut掉我的处理方法是:启动一个独立的线程,定时向连接发送一个请求。
    class DBSleepAvoid extends java.util.TimerTask 
    {
        public void run()
        {
         **.MyDebug.TRACEINFORMATION(this,"run","Send message to each DB connection...");
        
         MyDBConnectionPoolX.checkPools();
        }
    }
      

  11.   

    new java.util.Timer().schedule(new DBSleepAvoid(),200,1000*60*30);
      

  12.   

    1 如果你的数据库在本机,也就是应用和服务器在一个机器上,你可以让连接定时touch一下数据库,一般是 
    select 1 
    select 1 from dual之类的,根据数据库不同,使用任何一个没有意义的语句即可比如10分钟调用一次,这样可以保证链接一直有效。2 我很少遇到链接必须一直打开的。使用连接池,在用到时从池里获取,用完了马上归还(close());
    不用担心性能问题,连接池会保证可用性的。
      

  13.   

    楼主看看,可以参考以下下面的实现,这个类可以基于数据库链接池为你的程序提供一个稳定的Connection。
    需要用到commons-dbcp,commons-pool,commons-collections,可以到http://commons.apache.org下载
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.Properties;import javax.naming.InitialContext;
    import javax.naming.NamingException;
    import javax.sql.DataSource;import org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory;public class ConnectionManager {
        
        private static DataSource ds = null;
        
        public static Connection getConnection() throws SQLException {
            if (ConnectionManager.ds == null) {
                try {
                    ConnectionManager.ds = InitialContext.doLookup( "java:comp/env/jdbc/testdb" );
                }
                catch (NamingException e) {
                    Properties p = new Properties();
                    p.setProperty( "driverClassName", "com.mysql.jdbc.Driver" );// 你的数据库驱动类
                    p.setProperty( "maxActive", "4" );
                    p.setProperty( "maxIdle", "4" );
                    p.setProperty( "maxWait", "5000" );
                    p.setProperty( "password", "" );
                    p.setProperty( "username", "root" );
                    p.setProperty( "url", "jdbc:mysql://127.0.0.1/forum" );// 你的数据库链接URL
                    try {
                        ConnectionManager.ds = BasicDataSourceFactory.createDataSource( p );
                    }
                    catch (Exception ex) {
                    }
                }
            }
            return ConnectionManager.ds.getConnection();
        }
        
        public static void main(String [] args) throws SQLException {
            Connection conn = ConnectionManager.getConnection();
            // TODO:你自己的操作数据库代码
        }
        
        private ConnectionManager() {
        }
        
    }
      

  14.   

    肯定错误!!!自己去找原因!
    一般数据库的socket连接是数据库管理超时的。最好建个池!
      

  15.   

    确定在同一服务器下
    并且没有多用户访问的环境
    可以不考虑用池,毕竟用池也是一大块资源最简单的办法,做一个Thread
    然后每隔几分钟发送一个无意义select就可以
    比如
    select true
      

  16.   

    将Connection 修饰为static就ok了。