每个人的数据只涉及一行吗?那数据量怎么会很大呢,呵呵,难道有ntext,或者image类型的数据吗

解决方案 »

  1.   

    smart_zcg() ( ) 信誉:100    Blog  2007-01-25 15:54:52  得分: 0  
     
     
       每个人的数据只涉及一行吗?那数据量怎么会很大呢,呵呵,难道有ntext,或者image类型的数据吗
      
     
    --------------------------------------不是,每个人可能有上千行数据,数据都是普通的字符数据
    同时有几千人操作。由于每个人操作并不影响其他人数据,
    所以我想知道可不可以并行
    如果可以,数据库会不会自动提升行锁为表锁
      

  2.   

    另外,楼主问的可不可以从行级锁定?我想楼主的意思可能是说,用行级锁定能不能允许两个用户各自的事务在同一时间修改表中的两行吗?答案是:不能。
    原因是:一个事物在修改数据时使用行级排它锁后,表依然会被加意向排它锁,意向排它锁依然会阻止另一个事务同时进行的修改数据提交,除非表上的意向排它锁被释放掉(也就是说前一个事物的行级排它锁被释放掉,这样该事物的修改数据已经提交)。所以用行级锁定SQL SERVER也不能允许两个用户各自的事务在同一时间修改表中的两行数据。
      

  3.   

    --可以显示的要求SQL Server使用行所
    BEGIN TRAN 
    DELETE FROM table1 WITH (rowlock) WHERE username='zhangsan'
    INSERT INTO table1 VALUES ....
    COMMIT TRAN --锁升级的前提是没有使用 WITH (rowlock) 提示.
      

  4.   

    另外,在Table上建立一个用户名栏位的索引可以避免使用表锁.这一招非常有效.
      

  5.   

    使用什么样的锁是由SQL SERVER根据性能的负载平衡来决定的,用户最好不要干涉。不过你可以通过优化你的代码来防止锁升级,行锁升级成页锁甚至表锁等。比如你在更新100万行数据时可以用下面的办法,避免锁升级:set rowcount 500
    update_more:
         update [table] set A = .....
    if @@rowcount > 0
         goto update_more
    set rowcount 0
      

  6.   

    如果在上面的例子中更新100万条数据,楼主只是写了一个update语句并在上面提示使用行锁,然后直接提交,换来的只能是SQL SERVER的高资源使用。因为,SQL SERVER是为了降低资源的使用来提升锁的级别的,当然这样确实影响到了并发性。
      

  7.   

    我对数据库不是很懂,首先我没有使用存储过程,事务是在代码中实现的。
    另外,我的操作是删除,然后插入。没有更新。
    我知道的是,如果只是写的话,在2005里面,多个人应该可以同时写的。
    只是删除时候呢?是不是能够只锁定需要删除的行?
    为了描述清楚,我写些伪代码表UserId, UserInfo,
    0001, 数据1
    0001, 数据2
    0002, 数据3
    0003, 数据4
    0002, 数据5
    0001, 数据6
    客户段代码private void 更新数据()
    {
      try{
        开始事务;
        
        执行("delete from 表名 with UserId="+UserId);    insert="insert into 表名(UserId,UserInfo) values(@UserId, @UserInfo)";
        for(int i=0;i<3000;i++){
           para[“UserId”]=用户ID;
           para[“UserInfo”]=用户信息;
           执行;
        }    提交事务;
      }
      catch(Exception ex){
        回滚事务;
      }
    }
      

  8.   

    首先,insert,delete,update语句都是对数据修改的行为
    如果插入时,只涉及一行数据,没有什么好说的,因为执行时间很短。
    我前面所说的数据修改的问题,用update举的例子,对删除行为一样适用。
      

  9.   

    smart_zcg() 如果插入时,只涉及一行数据,没有什么好说的,因为执行时间很短。-----------------但是这些插入是放在了事务里呀。
    在提交前,必须保持每个锁吧
    还有前面删除的那些在提交前,也应该保持每个锁吧。
      

  10.   

    smart_zcg() ( ) 信誉:100    Blog  2007-1-25 16:51:10  得分: 0  
     
     
       
    主要是使用了事务,那么在事务开始后,一直到事务提交或者回滚之前,是怎么加锁的?
    ————————————————————————————————————排它锁会一直保持到事务提交或回滚后才释放  
     
    --------------------------------------------------那就是说,一个用户在开始事务,进行数据操作,一直到事务提交或者回滚,别的用户都只能等待了??????????????
      

  11.   

    smart_zcg() ( ) 信誉:100    Blog  2007-1-25 17:01:38  得分: 0  
     
     
       
    是的  
    -------------------------------------------------------------这是个不好的消息,如果每个用户插入数据需要5秒钟时间,那么6千人就需要3万秒,也就是500分钟,8个多小时!!!!!!!!!!!这绝对是不能忍受的。
      

  12.   

    也就是说原来有3000行,删除后,就要再加入3040行?
    ——————————————————————————
    为什么要这么做呢?难道被删除的和后来插入的行之间没有任何相关性吗?为什么不能去更新库中现有的行,再插入少量的数据就好了呢?如果一定要这么做的话,我觉得可以建两张表,一张是你现在操作的表(即主表),另一张是一张临时表,插入的时候先把数据放到临时表中,等业务空闲时,可以定期把临时表的数据导入到你的主表中(当然这需要系统自动完成),如果需要查询用户相关信息的时候,应该同时访问主表和临时表。
    对于数据的删除,最好不要用delete语句去物理删除行,这样做性能不好(因为这会涉及到表索引的更新)。楼主可以在表上另建一列,用来表示行状态,删除的时候只需要更新这一列的状态值,标记这些行为无效就行了。同样的,可以等到业务空闲的时候再删除这些无效的行。如果一定要按照你说的方案,先物理删除,再物理插入,而且是从客户端多次向数据库提交insert来实现多行插入,那我也没有太好的性能优化的办法了。说到插入,你还可以尝试先把要插入的列,按照一定的格式写到一个文件中,然后从文件批量导入到SQL SERVER性能或许能高一些。另外,我觉得在你们的业务实现上,客户端做的事情有点太多了,其实应该尽量把大多数的业务放到SQL SERVER上来实现才能获得最好的性能。
      

  13.   

    smart_zcg() ( ) 信誉:100    Blog  2007-1-26 13:41:02  得分: 0  -----------------------------------------------------谢谢,我查了一些资料,有些事情我稍微有点了解。我知道这样做不好,但是你也知道,有时候客户的要求很奇怪。(客户的有些要求,我还没有说,否则你肯定会说变态,呵呵)对于数据库,我们没有多少权限,所以不能在数据库上做很多事情。
    所以业务只能在代码中实现,不能移到数据库里。既然这样,我想用户操作的等待,只能在程序中做了,考虑一下怎么安排这个队列。
      

  14.   

    如果要在客户端实现业务,我觉得只能按照你的做法实现比较简单。另外,我给过你一个避免事务执行期间锁升级的demo,虽然你可以不使用存储过程来那么做,但是你也许可以在客户端写一个文本格式的sql批处理脚本,然后由客户端把批处理一起发送到数据库执行,这样也是一个不错的办法。
    最后,就是建议你操作的那张表上不要建聚集索引,也不要建立过多的非聚集索引,这样十分影响插入和删除的性能。
    别的我也没有什么太好的建议了。