原贴: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();
}
}大家看以上方法可行不可行
(也就要实现,一条记录只能让一个人读取出去操作)
谢谢
如我记录
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 0 N
2 0 N
3 0 N
4 0 N加个标记,先获取ID,设置为Y,然后不允许读取flag为Y的记录,如果出错,需要人工干预.
另外一种,就是加琐,好象上次已经告诉过你了.
第一次更新后sel = 1,第二次sel = 0的时候就取不出来了。
---------------------------------------
我对SQL还只是在查询语句上面
触发器没有写过,那上面的这个要求触发器要如何写呢谢谢
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别人就读不取这个可以使用乌龟的方法,在表中设置一个读取标志位。
大家现在不要看我的第一个方法,看我的新方法
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();
}
}
我说的这个办法怎么样谢谢
触发器应该是使用日志轮询来实现的,所以一定是队列方式的。100个并发是个很苛刻的要求了。即便是开心网强车位和偷菜也不见得有这个量(并发和同时在线的区别是很大的)。就一般的需求,只需要用一个存储过程就可以了,要先在事务中update后select,而不是先select后update。开启事务
更新表的一条记录
--这是别人读取就是表锁定状态
select更新过的记录
--这是别人读取就是表锁定状态
提交事务
的签名很有个性!!
{
//获取id
}这样获取id的任务会排队依次执行。
更过份的是,我现在看到warcraft这个单词就会下意识的以为是乳沟
--先取出一个号码,在插入时要判断表里是否已经有这个号码了,没有的话,插入数据。
--有的话,再取一个号码,再判断。。
--更新成功修改ID的标识。
--当然,肯定要用到事务的。
--不要一条一条的插记录,连接成一个字符串,一次性插入数据,保证速度。