两个问题
1。你用户多么办?要知道,连接是稀少资源
2。你听说过线程模型么?ADODB的线程模型是APARTMENT类型,你把连接对象放SESSION变量里,会造成性能急剧下降,而且有可能会造成死结(deadlock)

解决方案 »

  1.   

    最高效率的做法还就是在每张网页里打开、关闭连接。
    其次就是将连接放在 Application 里,但绝对不要放在 Session 里。
      

  2.   

    放在APPLICATION变量里也不好啊,想象一下,你有100个用户,大家都要争着使用你那APPLICATION变量的唯一连接对象,你说性能会好么?如果这个连接是共用的,并行操作有可能会对数据库造成破坏
      

  3.   

    最好的办法是封装在一个bean里面。
      

  4.   

    不需要放在session或者application里,因为连接本来就是在pool里共享的,windows已经这样做了,你就不需要再做一层共享,反而降低效率了,最好在每个页面下面将连接关闭,这样就足够了
      

  5.   

    saucer(思归)
    你的两个问题
    1。你用户多么办?要知道,连接是稀少资源
    2。你听说过线程模型么?ADODB的线程模型是APARTMENT类型,你把连接对象放SESSION变量里,会造成性能急剧下降,而且有可能会造成死结(deadlock)能解释一下吗?用户多有怎么样?少又怎么样?把连接对象放在session变量里,为什么会造成性能急剧下降?meizz(梅花雨) 你也说说理由好嘛?
      

  6.   

    我觉得在每个页面连接一次就够了,并且应该及时释放资源,事实上在你每次更新页面时,旧的连接已经释放,必须重新连接。
    并且如果你使用sql那么可以在数据库端避免死锁的发生,而且我觉得防盗Session是不负责人的行为,因为没人断定不会“丢失”,我是说在异常情况下资源没有及时释放,特殊情况下会塞车。
    Application仍旧是不明智的做法,正如meizz(梅花雨) 所说,大量请求通过统一渠道,采用串行,是不明智的,压力反而由于频繁的lock和unlock导致性能下降,虽然每连接人就需要lock但是那至来自于数据库,不包括application,
      

  7.   

    的判断很准确,开始我没有发现,后来发现他说的完全没有错误,我来解释为什么!
    ===================================
    帮你介绍一下线程模型的问题:
    1、Single-threaded:某一时刻只能有一个进程使用组件
    2、Apartment-threaded:若干进程都可以使用组件,但只有一个在只定的线程上面
    3、Multiple-threaded:若干进程都能使用组件,并且这些进程可以运行于不同的线程之上
    4、Both-threaded:对象既可以使单元线程,也可以是自由线程
    5、Neutral-threaded:若干个进程都可以使用某组件,并且可以使用指定的一祖线程中的任何一个(win2000中引入)
    然后具体介绍一下单元线程模型(Apartment-threaded):
    ============================================  首先asp使用vb,vb6.0支持两种线程模型,single和apartment。单元线程模型适合对于大多asp组件类型的开发,但是如果你使用session和application对象来存储ADO组件的实例,性能肯定是个问题,也许你应该使用自由线程和双线程模型,但是vb不支持,,这是因为vb不能编写多线程的应用程序(题外:Delphi万岁,被认为是同级别的语言,Delphi不知比vb好多少),者有意因为vb隐藏了线成的概念(傻瓜形)。首先ADO是使用单元线程模型的组件(事实上微软的大部分组件采用单元线程模型,其中一方面是考虑自己产品间的兼容性),这就意味着,组件的实例只能在STA中被创建,也就是COM确保对组件的单个实例的所有访问通过一个线程串行进行。同一线程可用来在对象生存期内调用组件的所有接口。
      做个假设,100个用户访问你的asp叶面中的ADO组件实例,每个调用都可以并行的处理,也就是说每个响应的时间相同.
    ======================================================
    以上为基础知识,下面就本贴子分析:
    前提条件:ADO是基于单元模型的组件(所以只介绍单元模型,不介绍其他情况)、结合asp说明(必须明确和asp无关,只与COM和组件作用的范围有关)、
    1、存放在session中:
         当你在session范围创建ADO对象时,最会话期内所有引用它的页面都可用,我想这是使用这种方式的原因。但这就意味者统一用户提出的多个页面请求都可以访问这个对象,于是请求无论何时进入ASP就从线程缓冲池中为特定的STA指定一个接口。但是ADO组件和创建它的STA具有线程类似性,只能运行于同一线程上。(我觉得还是有必要说一下其他类型的组件,如自由线程和中立线程模型,他们由于它们可以运行于多线程,他们更灵活;除了单一线程,但它的效率对于网络极差,虽然安全。)回到ADO,ASP检查会话,如果存在单元线程组件(这里是ADO),于是把请求传送给合适的线程,于是这里就存在了一个极其严重的问题,据个例子:假设同一时刻1000个请求了你的页面,但是缓冲池是有限的,于是服务器忙于处理大量的这种类型的线程请求,如果ADO运行所需的那个线程刚好被占用,那么ADO无法工作,于是ASP无法将请求传送给另外一个线程,只有等待这个线程可用为止。也就是说当大量的用户在Session中创建ADO,这些对象都被阻塞在一个特定的线程中了,服务器将很快找不到可用的线程,建议只占停不能做任何事情。太可怕了.( 题外话,但不说所有组件都不能,只是因为ADO是单元线程模型,它具有线程类似性;你可以在session中创建自由线程和双线程模型的组件);2、在Application中:
         如果你理解了在session中存在的问题,就不难理解在application中的问题了。在application中会变得更糟糕,因为所有用户间只有一个ADO实例,由于ADO是单元模型,那么进入服务器的任何请求都将被送到同一个线程,意味着所有访问站点的用户只有一个用户可以使用ADO,其他的只有等待,这就和单线程模型的组件(single-threaded)出现同样的问题,也就是说这种办法是绝对不能取的,绝对的低效率。
     当然,并不是所有组件都不可以存放于Application,对于自由线程模型和中立线程模型是可以的。
    ===============================================================
         ***对于上面的理解,你可以把我说的ADO和单元线程模型理解为同一事物,因为ADO基于单元线程模型。
     其实你可以在session和application 中存放ODBC||OLE DB连接字符串,在单一页面的connection实例中设置属性,存放一些常用的数据,我想者也存在问题,实在不想写下去了,手都累了,可写的东西太多了,不知道你看明白了吗?如果你不明白,很正常,主要是你的问题涉及到了COM技术,《COM+ in thinking》是本不错的关于COM技术的书籍。这个问题很牛嘛!事实上这个问题应该在COM论坛里,没想到在这里出现了,呵呵,学艺不精,希望没有误人子弟。我也是初学者,不过我看书很多(^_^)
    ================================
         结论最好不要在session中存储ADO。connection,当访问量大时效率很低;绝对不要再Application中存储ADO.connection,当访问量不是很大时效率极低!
         并不限于ADO,对于具有线程类似性的组件都存在这种问题,但并不是这些组件不好,只是你不应该这样使用。
      

  8.   

    saucer(思归)果然厉害,一针见血,我做了解释,不知道是不是正确。现在js越来越成熟了,
    近一个月没来js,心里早就痒痒了,看到这么多熟悉的“面孔”,爽!
      

  9.   

    asp里面没有办法打开一个持久的连接吗?我想有的话,就能够解决楼主的问题php有,用一个用户名和密码连结后,以后只要有新的连结(同用户名和密码)申请,就不会重新连结,而直接使用这个连结见:
    http://www.csdn.net/Expert/TopicView1.asp?id=970677
      

  10.   


        Globla.asa文件包含四个过程,即Application_onstrat、Application_onend、Session_onstrat、Session_onend,这四个过程时固定的,也就是说,在应用程序初始化文件里,只有这四个过程能被触发。
        Application_onstrat过程在应用程序第一次运行时被触发,在这个过程里,可以进行数据库操作,进行数据检索。当在这个过程中定义变量后,变量全局有效。由于有不同的程序可能同时调用Application对象,为了保证变量存储时的正确性,在变量存储时,要把Application对象锁定,即Application.Lock,存储后再开锁,Application.UnLock,这样才能保证整个应用程序运行过程中的稳定性。在整个应用程序运行过程中,Application对象的变量值都是有效的,我们可以用来存储一些公共的数值,比如访问人数,在线人数等等。
        Application_onend过程在应用程序关闭时被触发,但由于服务器在关闭程序时,往往不会等待应用程序的关闭,所以在Application_onend过程中的操作将不会被有效的执行,因此,Application_onend过程是不可靠的。
        Session_onstrat是用户向第一次应用程序第一页发出请求时被触发,这个过程为用户打开一个会话,保存用户的私人信息。在这个过程中,是不可以进行数据库的检索操作的。
        Session_onend过程是在应用程序结束一个用户会话时被触发,同样也不能进行数据库的检索操作。于是我们便在考虑设计时充分利用这一点,在globla.asa文件中约定好应用程序的全局变量。    通过这几段文字,基本可以解决上面提出的问题了。即在Session_OnEnd事件中不要进行任何数据库的操作。那么要实现本贴的需求,可以采用Davelu(豆腐)兄提到的方法。不过具体实施起来还有些细节的技术问题需要解决,并且这种方法的确是存在一定漏洞的。因此看来要给出一个完美的登录解决方案,不是Session技术能解决的了。
      

  11.   

    TO: vivanboy(我是谁?) 
    首先我不懂PHP,但我觉得本帖子的特点是使用ADO连接,是否使用一个持久的连接却绝于那个组件,你可以使用一个C++ ,Obj Pascal制作的自由线程或双线程的组件而在Session 甚至Application中保持一个持久的连接,但是你仍旧应该注意到COM+使用线程环来解决问题,也就是说当访问量过大时,多余的线程会产生一个新的环,也就是说即使你使用多线程的方式,那么访问量极大时产生的环过多,仍旧会慢下来,这是因为你过多的共享一个连接所至,所以我觉得还是在每页中及时释放连接资源是合理的方案,当然这应该具体情况具体分析,如果你的叶面不会像CSDN这样,你仍旧可以随便使用,但它是个隐患,确实是个不负责人的做法。个人看法!
      

  12.   

    我觉得如果访问量很大的话把连接放在application也未尝不可,
    多用户并行操作引发的冲突数据库会解决,不是我们考虑得到的,
    而且数据库连接在程序里面也是占用很大时间的,放在application里面的确好用的多,
    当然,前提是你的同时在线用户很多,比如,几百用户同时在线。
      

  13.   

    放在session里面,简直就等于自杀。为什么呢?一般session的生存气是20-30分钟,也就是说,一旦一个拥护近来然后马上又转到其他的网页,但是资源却没有释放。而是要等30分钟后在能释放,而你的系统假如有是多用户并发的,没个用户有一个数据库连接,当拥护过多,你的系统就可能down了。数据库的连接资源是非常珍贵的,并且,数据库连接操作都应该是随时的。所以,绝对不能放到session里面。
      

  14.   

    小网站可以放到session  大网站就不要用了,太占服务器资源。而且  有些浏览器并不支持session 。
      

  15.   

    同意ghj1976(蝈蝈俊.net) session本质是基于cookie的,所以有些浏览器不支持,就算支持,如果浏览器设置放弃使用cookie,那么放在session中同样达不到效果。对了,提供一个改变ADO对象的方法:
    \Program Files\Common Files\System\ado
    目录下有一个makefre15.bat可以把ADO转换成双线程对象,同时支持单元线程和自由线程模式,可以改善你的性能。还有一个makapt15.bat转换回去.=================
    这个贴子怎么没人看了,php有一个类似的帖子
    http://www.csdn.net/expert/topic/970/970677.xml?temp=.3425867