最近几天在整理以前的代码,在看到数据连接时想到了下面的问题。通常我们可能有以下两种方式来使用数据库连接。
1、每客户端一个全局连接;
2、每客户端多个连接。
由于数据库存在接入点限制的时候,代码应该是尽可能保证是一个客户端一个全局Connection,所以我这里假设数据库不存在接入点限制。那么在这种情况下,是多个连接效率高,还是一个连接效率高呢?
那这里可能需要将数据库服务器配置分为两种情况:
1、服务器以及数据库性能足够高 那么此时每客户端是多个连接效率高还是单连接高?
2、服务器以及数据库性能一般   那么此时每客户端是多个连接效率高还是单连接高?写下来之后发现这个问题似乎是属于数据库并发连接处理能力的问题 - - 

解决方案 »

  1.   

    现在的建议应该是打开连接后及时关闭连接,而不是一直连上服务器上增加服务器的开销,在ADO.Net中,连接池可以有效的保障断开后重连的效率。
      

  2.   

    个人感觉仅供参考:
    1、从客户端windows消息排队,CPU处理时间划片来讲,即便开多线程基本也不会有什么区别;另外网速度是一个问题。
    2、服务器以及数据库性能一般,并发连接越多,可能性能越差。
      

  3.   

    ADO支持事务的,ConnectionTimeout应该设置等待尝试连接打开的时间,如果在这个时段内连接失败会返回一个错误,这个和事务操作时间没关系的吧....
      

  4.   

    这个问题在JAVA块已经提过了,只不过它提的形式和这个不同,后台连的是ORACLE,
    他的问题是,同一级别的页面里面是用同一个CONNECT还是用多个CONNECT,这里面有什么区别?其实,我观点还是缓冲池的问题,当一个CONNECT新建完毕后,这条指令将贮留在缓冲池中,那么当此CONNECT有新的指令发送出,它第一个匹配缓冲池的已执行命令,而不是直接去执行(这里面存在一个执行力的问题,并不是老板叫你去做什么你马上就去做就是最佳答案,而是先分析一个老板的问题,再去执行),当匹配缓冲池中的命令都没有合适时,它会新建新的指令,并去执行,如果匹配到有效的缓冲池指令,那么它会直接在此指令中增,删,改缓冲池中的某条指令,而不会去新建,那么这么做它的劣势在哪里呢?常时间的利用同一个CONNECT,缓冲池中的指令会出现"脏"指令,这时,你写代码的人并不会知道,但它却在缓冲池中形成了,匹配的力度将大加服务器的负荷而导致数据读入内存的速度变慢.
    而如果一直使用新的CONNECT,那么缓冲池的做用被大大缩小了,这样的话,对于一个大型网站来讲,它相当于放弃了这块功能,这是被他们绝对不允许,所以,当你的程序里面真的要讨论到这个问题时,需要在SQL内部用它的执行消耗功能,测试在大批量指令的情况下,如何来调整你的CONNECT,而不是像考试一样,来回答这个问题.
      

  5.   

    :) ADO的事务是调用数据库的事务。当指令大到无法在ConnectionTimeout内完成的时候也会提示TimeOut Expired的。
      

  6.   

    不知道楼主有没有考虑下license的问题。
    我的单位用的是informix.是concurrent的license。
    多一个多个钱。
    无关的话。
      

  7.   

    我在0楼已经说了-->
    由于数据库存在接入点限制的时候,代码应该是尽可能保证是一个客户端一个全局Connection,所以我这里假设数据库不存在接入点限制。那么在这种情况下,是多个连接效率高,还是一个连接效率高呢? 
      

  8.   

    还可以从数据库端研究这个问题
    Oracle是有连接数限制的,65536个(好像是,我没有查证)
    可以用分布数据库技术、链接数据库技术等分担主库的压力。
      

  9.   

    我发现过很多这样的用法。
    如9楼vbman所说,即用即连即断是个放之四海而皆准的好习惯,其他的不用考虑太多。
      

  10.   

    ADO的事务是调用数据库的事务。当指令大到无法在ConnectionTimeout内完成的时候也会提示TimeOut Expired的。
    ------------------------
    我觉得这个不正确,ConnectionTimeout只是响应连接时间,默认是15,如果在这个时间内连接不上数据库,则返回错误,如果在这个时间内连接上了,只要你不主动close,你可以无限时间连接,对其进行操作。比如你可以在程序启动时就连接数据库,直到程序关再在断开连接....所以我认为事务所用时间应该和ConnectionTimeout无关吧...
      

  11.   

    ConnectionTimeout和事务执行时间的测试:
    Option ExplicitPrivate Declare Function timeGetTime Lib "winmm.dll" () As LongPrivate Sub Command1_Click()
        Call TestTransTimeOut
    End SubPrivate Sub TestTransTimeOut()
    On Error GoTo Trans_Err    Dim cn As ADODB.Connection
        Dim strCnn As String
        Dim strCmdChange As String
        Dim strCmdRestore As String
        Dim booChanged As Boolean
        Dim intTrans As Integer
        Dim dt
        
       '打开连接。
        Set cn = New ADODB.Connection
        cn.ConnectionTimeout = 2         '尝试连接时间定义为2秒
        strCnn = "Provider=sqloledb;" & _
            "Data Source=192.168.0.179;Initial Catalog=pubs;User Id=sa;Password=MOFZaCW3Ob; "
        cn.Open strCnn
        
        '记录连接后的时间
        dt = timeGetTime
        
       '定义命令字符串。
        strCmdChange = "UPDATE titles SET type = 'self_help' " & _
            "WHERE type = 'psychology'"
        strCmdRestore = "UPDATE titles SET type = 'psychology' " & _
            "WHERE type = 'self_help'"
       
        '开始事务
        intTrans = cn.BeginTrans
        '异步执行命令
        cn.Execute strCmdChange, , adAsyncExecute
       
        '做一会其他的事情
        Do While timeGetTime - dt < 30000  '设置一个大于ConnectionTimeout的时间
            DoEvents
            Debug.Print timeGetTime - dt
        Loop    '如果命令没有完成,取消执行并回卷事务。否则提交事务。
        If CBool(cn.State And adStateExecuting) Then
            cn.Cancel
            cn.RollbackTrans
            booChanged = False
            MsgBox "Update canceled."
        Else
            cn.CommitTrans
            booChanged = True
            MsgBox "Update complete."
        End If
       
        '如果已经更改,则恢复数据,因为这只是演示。
        If booChanged Then
            cn.Execute strCmdRestore
            MsgBox "Data restored."
        End If  intTrans = 0 
        cn.Close
    Trans_Exit:
        Set cn = Nothing
        Exit Sub
        
    Trans_Err:
        If intTrans = 1 Then cn.RollbackTrans
        MsgBox Err.Description
        Resume Trans_Exit
    End Sub可见,事务处理错误提示TimeOut Expired,应该和ConnectionTimeout大小无关...应该是其它原因
      

  12.   

    估计你的问题可能来自于CommandTimeout....
    ConnectionTimeout属性设置尝试连接的时间,连接成功不会影响操作命令的执行时间,所以可以根据情况设置较短的时间,在网络好的情况下,意外连接不上也就不必忍受“30秒的等待”....
    CommandTimeout属性,设置 Execute 方法调用的时间。如果在 CommandTimeout属性中设置的时间间隔内没有完成命令执行,将产生错误,然后 ADO 将取消该命令。如果将该属性设置为零,ADO 将无限期等待直到命令执行完毕。但它也是针对一个Execute方法而言,不是整个事务的执行时间。楼主的“TimeOut Expired”会不会是因为某个execute执行超时?比如你长时间的事务致使服务器负载过重产生延迟?CommandTimeout默认为30秒...事务可在一段相当长的时间内分配和保持数据源上的有限资源,因此建议事务的存在时间越短越好...
      

  13.   

    辛苦了,或许是我之前搞错了,但我记得很久以前测试的结果是这样的:
    写一个很长的更新语句放在一个事务内部,更改TimeOut时间可以看到效果的。
      

  14.   

    辛苦了,或许是我之前搞错了,但我记得很久以前测试的结果是这样的: 
    写一个很长的更新语句放在一个事务内部,更改TimeOut时间可以看到效果的。 
    -----------------------
    不辛苦,一起研究,呵呵 
    恩我想你更改的一定是CommandTimeout而不会是ConnectionTimeout
    ,设置不同的CommandTimeout,是会影响到某个很长的update语句的执行成败,不能成功执行的语句抛出的错误致使整个事务的失败...你可以尝试设置较长时间的CommandTimeout,来保证保证每一个SQL语句的执行,甚至设置CommandTimeout=0,不过这样一来万一数据库产生阻塞有可能会不报错而使程序死在那儿...我们公司原来的老系统遇到过这样的问题,是其它语言写的...
    总之提倡即用即连即断,尽量使用短时间的事务,没必要就不要同时采用多个连接...推到源头,合理的系统框架和数据库结构非常重要...
      

  15.   

    我使用的也是全局,只在系统退出时关闭因为需要用到conn的地方实在太多,反复的断、连 很麻烦不说,也不便管理。