原贴:http://topic.csdn.net/u/20090329/16/d70875f4-5b5d-4342-b620-d795c4b6c6c7.html?1136603018
如我记录 
tab 
ID Sel 
1  0 
2  0 
3  0 
4  0 
然后现在有100个人来同进进行一个操作 
就是 
1: 
select top 1 ID from tab where sel = 0 
在读出来的同时更新这个sel为1 
这里的SQL要怎么写,谢谢 2: 
当进行并发的时候又不会对记录重复读取, 
也相当于有人读取了记录1别人就读不取 谢谢
---------------------------------------
大家都说了用加锁的方法,但我感觉用锁不是很好
所以我想了个方法,不知道可行不可行
以下没有按语法写,大概意思是这样
首先Int32 GetOperationID()
{
Int32 ID
ID = oo.ExecScalar("select top 1 ID from tab where sel = 0 ");  //这里取出一个别人未操作的ID
if(oo.ExecNonQuery("update tab set sel=1 where id="+ID.ToString())); //这里进行更新,用更新返回的记录数来判断当前的记录是否已经初读取
{
    return ID;
}
else
{
   GetOperationID();
}
}大家看以上方法可行不可行
(也就要实现,一条记录只能让一个人读取出去操作)
谢谢

解决方案 »

  1.   

    ID Sel flag
    1  0   N
    2  0   N
    3  0   N
    4  0   N加个标记,先获取ID,设置为Y,然后不允许读取flag为Y的记录,如果出错,需要人工干预.
    另外一种,就是加琐,好象上次已经告诉过你了.
      

  2.   

    加一个timestamp列,读的时候读出它的值,更新的时候用它作为条件
      

  3.   

    用触发器就应该可以,他会处理并发的情况。
    第一次更新后sel = 1,第二次sel = 0的时候就取不出来了。
      

  4.   

    RE:用触发器就应该可以,他会处理并发的情况。
    ---------------------------------------
    我对SQL还只是在查询语句上面
    触发器没有写过,那上面的这个要求触发器要如何写呢谢谢
      

  5.   

    1: 
    select top 1 ID from tab where sel = 0 
    在读出来的同时更新这个sel为1 楼主的要求应该是矛盾的吧。进行读取的时候,会默认为该表加一个共享锁,这个时候如果该事务没有完成时没办法进行更新的,也就是说是读出的同时更新sel是不行的,除非在查询的时候指定不加锁。select top 1 ID from tab (with nolock) where sel = 0 
    2、当进行并发的时候又不会对记录重复读取, 
    也相当于有人读取了记录1别人就读不取这个可以使用乌龟的方法,在表中设置一个读取标志位。
      

  6.   

    RE:

    大家现在不要看我的第一个方法,看我的新方法
    Int32 GetOperationID()
    {
    Int32 ID
    //这里取出一个别人未操作的ID
    ID = oo.ExecScalar("select top 1 ID from tab where sel = 0 ");  
    //这里进行更新,用更新返回的记录数来判断当前的记录是否已经初读取
    //如果更新大于0说明当前选出来的ID别人还没有选取且未更新
    //为果为0的话说明已经被别人获取了,那么就重新选一个ID
    if(oo.ExecNonQuery("update tab set sel=1 where id="+ID.ToString())>0);{
        return ID;
    }
    else
    {
       GetOperationID();
    }
    }
    我说的这个办法怎么样谢谢
      

  7.   


    触发器应该是使用日志轮询来实现的,所以一定是队列方式的。100个并发是个很苛刻的要求了。即便是开心网强车位和偷菜也不见得有这个量(并发和同时在线的区别是很大的)。就一般的需求,只需要用一个存储过程就可以了,要先在事务中update后select,而不是先select后update。开启事务
    更新表的一条记录
    --这是别人读取就是表锁定状态
    select更新过的记录
    --这是别人读取就是表锁定状态
    提交事务
      

  8.   

    playwarcraft
     的签名很有个性!!
      

  9.   

    还有一种方法是客户端的锁定。比如.net的web页面中可以这样写lock(静态对象变量)
    {
      //获取id
    }这样获取id的任务会排队依次执行。
      

  10.   


    更过份的是,我现在看到warcraft这个单词就会下意识的以为是乳沟
      

  11.   

    --怎么感觉象ERP系统单据在保存时,取单据号码的情况。
    --先取出一个号码,在插入时要判断表里是否已经有这个号码了,没有的话,插入数据。
    --有的话,再取一个号码,再判断。。
    --更新成功修改ID的标识。
    --当然,肯定要用到事务的。
    --不要一条一条的插记录,连接成一个字符串,一次性插入数据,保证速度。