首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 高分求助如何使一个connection一直保持打开的状态? [已结贴,结贴人:slam21]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-22 10:32:24 楼主
    我现在有一个java application,命令行下运行的,需要连续运行几个月的时间。

    大概的程序流程就是使用socket接收和发送数据,现在都是用jdbc方式获得connection并使用的。

    我的问题是担心在运行一段时间后,这个connection会被数据库关闭掉。。。

    有没有办法维持一个connection一直保持可用状态呢?

    这个系统只有这一个connection,不必担心多用户的问题。
    50  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • oxoxo
    • 等级:
    发表于:2008-04-22 10:42:091楼 得分:0
    这个好说啊,把这个connection做成静态的,写个方法,其他地方请求连接时都调用这个方法,这个方法判断connection是否为空,为空就重新构建一个连接,不为空就返回
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-22 13:17:222楼 得分:5
    如果你的connection是数据库的connection。那你的设计问题可就大了。多用户的时候你是必须考虑线程同步的问题~~

    引用楼主 slam21 的帖子:
    大概的程序流程就是使用socket接收和发送数据,现在都是用jdbc方式获得connection并使用的。


    对于你这句话我没有理解。你的前一句话也似乎也在说你的连接方式是socket的长连接。这个连接的地址是从数据库中获

    得并去连接的意思吗?

    一般的连接最好还是以池的方式体现出来。既然你的系统中存在多用户的状况,对于每个用户从系统的角度来说都应该是并行

    的。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-22 15:26:183楼 得分:5
    在使用之前, 判断这个连接是否有效, 如果有效, 直接使用, 如果无效, 先释放这个连接, 然后再为这个连接的引用创建一个新的连接.
    连接池好像也是这么处理的.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-22 16:23:154楼 得分:5
    使用连接池,它会自动给你管理连接的,你只要用的时候从连接池里获取链接就行了。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-22 17:17:225楼 得分:0
    to pizzame :长连接是我与socket server的连接方式,数据库的连接是jdbc,我问的问题是关于数据库连接的

    我的系统只有一个用户,就是说的这个。

    我是用java 直接运行class文件的,这样也能用连接池吗?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • gxwsxj
    • 等级:
    发表于:2008-04-22 17:56:126楼 得分:0
    学习一下
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-22 18:08:557楼 得分:0
    感觉没有必要一直开着一个连接。
    用的时候再开不是更好么?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-22 18:13:278楼 得分:0
    我是用java 直接运行class文件的,这样也能用连接池吗?
    可以啊.
    连接池不一定是写在配置文件里的啊.
    你可以自己实现 Connection 接口 重写里面的 close() 方法
    然后 定义一个集合 来做一个简单的连接池
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-22 22:35:129楼 得分:5
    这些都是数据库连接池考虑的问题,如果像楼上所说的调用 close() 方法,
    并不关闭连接,需要采用 JDK 的动态代理重写 close() 方法。

    如果是担心长时间连接断掉的问题,那就复杂了。要采用一个线程来监视这个
    Connection,当它被数据库强行断开了,就马上重连,呵呵,说说很简单,
    实现是相当复杂的。

    建议楼主不要考虑自己实现了,要考虑的问题很多很多。用一个字概括就是:难

    可以考虑使用开源的数据库连接池,比如:C3P0、DBCP 等。如果只需要一个
    连接配置成一个就可以了,既方便又好使,为什么不用呢?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-22 22:43:2010楼 得分:15
    我是用java 直接运行class文件的,这样也能用连接池吗?

    可以把连接池配置在 ConnectionFactory 类中,使用时采用

    Connection con = ConnectionFactory.getConnection();

    其他的与 JDBC 方式相同,照样 con.close(); 掉

    下面是 C3P0 ConnectionFactory 的参考:

    Java code
    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 }

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-22 22:48:0511楼 得分:5
    连接池并不一定要挂在应用服务器上的,也不是只有 Web 程序能用的。
    一个简单的 main 方法就可以用了。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-30 11:48:2812楼 得分:0
    楼上的兄弟,可否把这个包里代码铁出来看看啊。
    import com.mchange.v2.c3p0.ComboPooledDataSource;
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-05 17:13:5413楼 得分:0
    该回复于2008-05-05 17:39:32被版主删除
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-12 14:37:2214楼 得分:0
    up
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-12 23:22:4015楼 得分:0
    看不懂~UP
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-12 23:47:1216楼 得分:0
    后来搞个线程定时做点什么操作,就可以保持连接了。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-13 10:19:2617楼 得分:0
    为啥非得一直开着?
    不明白
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-06-27 23:16:1618楼 得分:0
    用到了连接池
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-06-28 09:57:5319楼 得分:0
    担心多余

    完毕
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-06-28 09:57:5520楼 得分:0
    此回复为自动发出,仅用于显示而已,并无任何其他特殊作用
    楼主【slam21】截止到2008-06-28 09:57:53的历史汇总数据(不包括此帖):
    发帖数:17                发帖分:375               
    结贴数:12                结贴分:355               
    未结数:5                  未结分:20               
    结贴率:70.59 %            结分率:94.67 %           
    楼主加油
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-06-28 10:43:4321楼 得分:0
    引用 19 楼 yetaodiao 的回复:
    担心多余

    完毕

    呵呵,绝对不是多余,因为我做了类似的事情,那些Connection长时间不用,对象本身还在,但是到数据库的实际连接被DBMS cut掉

    我的处理方法是:启动一个独立的线程,定时向连接发送一个请求。

    Java code
    class DBSleepAvoid extends java.util.TimerTask { public void run() { **.MyDebug.TRACEINFORMATION(this,"run","Send message to each DB connection..."); MyDBConnectionPoolX.checkPools(); } }
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-06-28 10:44:2122楼 得分:0
    new java.util.Timer().schedule(new DBSleepAvoid(),200,1000*60*30);
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-06-28 10:45:3823楼 得分:0
    引用 16 楼 coolzyt 的回复:
    后来搞个线程定时做点什么操作,就可以保持连接了。


    haha
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-06-28 17:35:5424楼 得分:0
    学习。。。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-06-28 18:21:0525楼 得分:5
    1 如果你的数据库在本机,也就是应用和服务器在一个机器上,你可以让连接定时touch一下数据库,

    一般是
    select 1
    select 1 from dual

    之类的,根据数据库不同,使用任何一个没有意义的语句即可

    比如10分钟调用一次,这样可以保证链接一直有效。

    2 我很少遇到链接必须一直打开的。使用连接池,在用到时从池里获取,用完了马上归还(close());
    不用担心性能问题,连接池会保证可用性的。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-06-30 11:18:2026楼 得分:0
    回帖是一种美德!传说每天回帖即可获得 10 分可用分! 连续两周技术区参与者,每周额外可以获得88个可用分
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-07-01 13:22:1127楼 得分:5
    楼主看看,可以参考以下下面的实现,这个类可以基于数据库链接池为你的程序提供一个稳定的Connection。
    需要用到commons-dbcp,commons-pool,commons-collections,可以到http://commons.apache.org下载
    Java code
    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() { } }


    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-07-01 15:02:3928楼 得分:0
    引用 1 楼 oxoxo 的回复:
    这个好说啊,把这个connection做成静态的,写个方法,其他地方请求连接时都调用这个方法,这个方法判断connection是否为空,为空就重新构建一个连接,不为空就返回

    肯定错误!!!自己去找原因!
    一般数据库的socket连接是数据库管理超时的。最好建个池!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-07-02 12:43:3729楼 得分:0
    严重同意:
    会引发很多不可与其的结果。
    脏读、幻影
    这列问题肯定会出现。
    引用 2 楼 pizzame 的回复:
    如果你的connection是数据库的connection。那你的设计问题可就大了。多用户的时候你是必须考虑线程同步的问题~~

    引用楼主 slam21 的帖子:
    大概的程序流程就是使用socket接收和发送数据,现在都是用jdbc方式获得connection并使用的。


    对于你这句话我没有理解。你的前一句话也似乎也在说你的连接方式是socket的长连接。这个连接的地址是从数据库中获

    得并去连接的意思吗?

    一般的连接最好还是以池的方式体现出…
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-07-02 15:06:3730楼 得分:0
    确定在同一服务器下
    并且没有多用户访问的环境
    可以不考虑用池,毕竟用池也是一大块资源

    最简单的办法,做一个Thread
    然后每隔几分钟发送一个无意义select就可以
    比如
    select true

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-07-02 16:48:2631楼 得分:0
    将Connection 修饰为static就ok了。
    修改 删除 举报 引用 回复