none
多个人访问数据库 每人判断数据库是否打开后出现的问题 RRS feed

  • 问题

  •  甲访问一个页面数据
    此时数据库连接为打开状态且未操作完毕
    乙在此时访问一个页面
    此时判断数据库连接是否打开
    打开就执行操作------此时有个问题 当乙未操作完毕而甲把连接关闭了会怎么样?
    不打开就打开------------此时 如果出现多个人同时打开 不会有问题吧?
    2009年2月16日 6:49

答案

  •   数据连接原则
    及晚打开
    及早关闭
    非事务的多操作不共用连接




    应该每个人都使用一个平时关闭的  只有在读取数据的时候才临时打开的连接


    所以
    数据库本来就是会出现多个人同时打开


     如果出现多个人同时打开 不会有问题吧?
    会有数据并发性错误  但是可以通过别的办法检查


    梁赫群是榜样 赵正平是偶像 恩?还有个人么?
    2009年2月16日 8:13
  • 针对楼主第一帖的问题,最好的办法是甲乙各自创建自己的数据库连接,只要符合尽晚打开、尽早关闭原则就不会数据库有什么不良影响。如果一定要共享连接的话,则需要甲乙之间订立约定,比如,谁打开的数据库连接,谁就负责关闭,另一方如何发现数据库连接已经处于打开状态,则在操作完成后,也不需要执行关闭操作。

    理解的越多,需要记忆的就越少
    2009年2月19日 5:38
    版主

全部回复

  •   数据连接原则
    及晚打开
    及早关闭
    非事务的多操作不共用连接




    应该每个人都使用一个平时关闭的  只有在读取数据的时候才临时打开的连接


    所以
    数据库本来就是会出现多个人同时打开


     如果出现多个人同时打开 不会有问题吧?
    会有数据并发性错误  但是可以通过别的办法检查


    梁赫群是榜样 赵正平是偶像 恩?还有个人么?
    2009年2月16日 8:13
  • 我们默认 甲乙2个人同时打开数据库  操作 table1 的 a字段  原来等于0   他们都试图让 id=1的 a=a+1

    目前他们的操作是并发的  操作如下

    甲 select a from table1  where id=1    得到a=0

    乙select a from table1  where id=1   得到a=0

    甲在客户端  a=a+1   得到newa  =1
    甲 update table1 set a=@newa  where  id=1  /更新a=1

    乙在客户端  a=a+1   得到newa  =1
    乙 update table1 set a=@newa   where  id=1  /更新a=1

    这个时候  a本来应该等于二 但是目前却等于了1。

    这种情况就是并发错误


    这样的错误如何检查呢?
    其实把更新语句修改下就好了

    update table1 set a=@newa   where  id=1 and a=@olda

    客户sqlda端发现更新影响行数为0  会throw一个exception


    这时候客户端可以重新读取干净的数据  重新操作



    tableadelpter 已经提供了很完备的并发完整性检查
    在没有使用  EF的状况下    建议使用强类型的Dataset 和tableadepter




    梁赫群是榜样 赵正平是偶像 恩?还有个人么?
    2009年2月16日 8:22
  • 这个是数据并发的问题
    而我的是数据库是否关闭的问题
    甲 在1.00秒打开数据库执行操作
    乙在1.12秒打开数据库执行操作
    因为甲的数据库连接状态是打开的
    所以乙不必再打开一个数据库连接

    而在2.00秒是 甲数据执行完毕 关闭数据库
    此时乙还未执行完操作 仍然需要数据库保持打开状态 但次时 连接却被甲关闭了

    2009年2月18日 3:37
  • 韦恩卑鄙 说:

      数据连接原则
    及晚打开
    及早关闭
    非事务的多操作不共用连接




    应该每个人都使用一个平时关闭的  只有在读取数据的时候才临时打开的连接


    所以
    数据库本来就是会出现多个人同时打开



    我在第一次回复的时候已经说得很清楚了




    简单的说  “创建一条连接的开销” 小于  "维护一条连接的开销"

    而且
    甲正在批量进行数据操作的时候  这条连接并不能被乙安全的使用


    所以共用一条连接不但没有意义   而且会造成持续保持连接对象造成额外的开销  引发错误 、、、


    梁赫群是榜样 赵正平是偶像 恩?还有个人么?
    2009年2月18日 4:05
  • 我觉得数据库本身就能够解决并发的问题,另外,在程序中也应该避免并发问题,例如.NET本身就有的sqldataadapter,sqlcommand等等就基本上能够解决并发问题。

    并发问题太多了,但是现在也比较有好的解决方案,我觉得你的做法不太对,而且基本上可以不用考虑这个问题(只是注意就可以了),因为数据库本身应该就有优化处理。例如你说的,打开网站执行操作,另外一个用户不可能等待你操作完了再执行操作,那有10000个用户,都要等死了。。

    所以这个也和数据库产品有关,编程上,只要注意关闭不必要的连接即可,更新时才打开链接,每个人都会有一个链接,这些链接会有连接池。所以这个地方不会有问题。当某个用户执行某个操作时,他其实占有一个链接。

    Jing Guo's Facebook profile
    2009年2月18日 6:47
    版主
  • 根据西红柿的回答 我把主题明确化

    代码打开数据库方式如下
    if(conn.state == connectionstate.closed())
    {
          conn.open();
    }

    以上为打开数据库方式
    使用适配器 ds 接收数据



    甲和乙是否公用一个连接
    甲关闭连接后乙正在处理数据 此情况是否为并发
    当佳关闭连接后 乙是否仍然可以执行操作?
    如果乙仍然可以操作 当乙执行完毕后 默认会执行一个conn.close()的方法 此时关闭的为乙占用的连接?此连接从何迩来?
    如果乙不可以操作 此时会报错 还是 中断所有执行?


    我曾经看过一个论坛代码 使用了一个bool值来判断是否关闭一个数据库 恩。。貌似有点头绪了
    但还是希望 提供以上问题的答案

    谢谢~~~~~~~~~~~~~

    2009年2月19日 4:06
  • 从1999年就用ado的人告诉你
    并发操作共用连接是没事找事
    那个论坛代码的技术是以讹传讹  
    发布出来是害人害己

    就凭他这么一判断  connection pool  几千行代码都成白费了





    VB :挺熟 API :不懂 C# :一般  .Net framework : 挺熟  ADO.net Dataset :吃饭的玩意 LinQ :支持 to XML to Object to Dataset 反对 to SQL to Ent
    2009年2月19日 4:54
  • singledark 说:

    根据西红柿的回答 我把主题明确化

    代码打开数据库方式如下
    if(conn.state == connectionstate.closed())
    {
          conn.open();
    }

    以上为打开数据库方式
    使用适配器 ds 接收数据



    甲和乙是否公用一个连接
    甲关闭连接后乙正在处理数据 此情况是否为并发
    当佳关闭连接后 乙是否仍然可以执行操作?
    如果乙仍然可以操作 当乙执行完毕后 默认会执行一个conn.close()的方法 此时关闭的为乙占用的连接?此连接从何迩来?
    如果乙不可以操作 此时会报错 还是 中断所有执行?


    我曾经看过一个论坛代码 使用了一个bool值来判断是否关闭一个数据库 恩。。貌似有点头绪了
    但还是希望 提供以上问题的答案

    谢谢~~~~~~~~~~~~~


    甲和乙是否公用一个连接
    完全要看conn对象的作用域  你根本没写出这个conn所在的类的生命和用法  如果每人有一个conn所在的类的实例 当然不是共用

    闭连接后乙正在处理数据 此情况是否为并发
    取决于上一个问题


    当佳关闭连接后 乙是否仍然可以执行操作?
    如果是共用则不可以


    如果乙仍然可以操作 当乙执行完毕后 默认会执行一个conn.close()的方法 此时关闭的为乙占用的连接?此连接从何迩来?
    如果乙不可以操作 此时会报错 还是 中断所有执行?
    你完全等于没贴代码 没法判断



    1 共用连接就是不对的 
    2 你说的代码是否共用连接 根据你贴的信息根本无法判断



    VB :挺熟 API :不懂 C# :一般  .Net framework : 挺熟  ADO.net Dataset :吃饭的玩意 LinQ :支持 to XML to Object to Dataset 反对 to SQL to Ent
    2009年2月19日 5:00
  • 针对楼主第一帖的问题,最好的办法是甲乙各自创建自己的数据库连接,只要符合尽晚打开、尽早关闭原则就不会数据库有什么不良影响。如果一定要共享连接的话,则需要甲乙之间订立约定,比如,谁打开的数据库连接,谁就负责关闭,另一方如何发现数据库连接已经处于打开状态,则在操作完成后,也不需要执行关闭操作。

    理解的越多,需要记忆的就越少
    2009年2月19日 5:38
    版主
  • 所以  我看的那个源代码里家了一个 MustClose的bool值来判断

    但 很多人访问时用这一个连接 可能会延迟

    卑鄙能不能提供一个不公用一个连接的代码示例?(或你通常写的连接语句)
    2009年2月20日 1:04