如何进行表的读取锁定

kzy7517 2006-06-22 12:50:57
刚从oracle转过来,向各位学习。
有一需求,生成流水(不用identity方式)。在oracle中如下
begin
lock table 独占模式;
select 当前ID号(返回值);
update 当前ID=当前ID+1;
end;

先锁表是为了防止多用户并发操作时select到了相同的值而返回重复的结果
请问在SQL Server中应如何写?
...全文
292 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
dichun 2006-06-27
  • 打赏
  • 举报
回复
WITH TABLOCK 是表锁
那你可以用表锁是可以的,
也可以用事务锁,选择事务锁的最低级,你再用的时候别人用不了,是串行操作。
我们也经常用到这个,
suntt 2006-06-27
  • 打赏
  • 举报
回复
示例如下:
事务A:
begin tran
select * from t with(tablockx)
waitfor delay '00:00:05'
commit tran

事务B:
sp_lock

sp_lock的显示结果(部分):
spid dbid ObjId IndId Type Resource Mode Status
------ ------ ----------- ------ ---- ---------------- -------- ------
...
56 1 273436048 0 TAB X GRANT
58 1 85575343 0 TAB IS GRANT
59 16 0 0 DB S GRANT
...

可以看到objID=t Mode是排他锁,type resource为tab

suntt 2006-06-27
  • 打赏
  • 举报
回复
--对读取的排他是加tablockx而不是tablock
select @MaxID=max(ID) from tb with(tablockx)
kzy7517 2006-06-26
  • 打赏
  • 举报
回复
不好意思,对SQL Server不太熟悉

zjdyzwx(十一月猪) ( ) 信誉:100
SQL读会锁定吗?例如,Tran1 Select 此时值为1,在更新前,刚好另一进程调用此过程,这样,Trans2 Select 出的值仍为1,这样,Tran1,2都取到了1这个值而重复(并发问题)。
所在我们在Oracle中,先锁表。Trans1 锁表,Trans1 Select 1,这是,即使有另一进程,也会先执行Trans2 锁表(执行不成功,等待),不能执行 Trans2 Select。直到Trans1 update = 2,且解锁(commit)后,Trans2才能执行 Trans2 锁表,Trans2 Select (此时取到是2,正确)。

liangpei2008(我爱世界杯) ( ) 信誉:100
请问WITH TABLOCK 是表级锁定还是行级锁定?

十一月猪 2006-06-22
  • 打赏
  • 举报
回复
你update 的时候 会自动产生排他锁(X)
比如
tran1:
begin tran
update t set col1 = 1 where col2 = 2

tran2:

begin tran
update t set col1 = 2 where col2 = 2

tran2 就会被阻塞
liangpei2008 2006-06-22
  • 打赏
  • 举报
回复
--事例
Create Function F_GetID()
Returns Varchar(10)
As
Begin
Declare @S Varchar(10)
Select @S= 'LZ'+Right(100000000+IsNull(Right(Max(ID),8),0)+1,8) From t1 WITH(XLOCK,PAGLOCK)
Return @S
End
liangpei2008 2006-06-22
  • 打赏
  • 举报
回复
WITH TABLOCK --锁表

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧