如何对记录行进行加锁?

xiays 2003-08-26 09:17:50
主要考虑多用户同时操作一个表时,万一两个用户同时操作一个表时会出错
假如我有一个表,表中只有一行记录(永远只有一行,修改时使用UPDATE)
用来存储最大ID 每次调用一个存储过程 实现 ID+1 并返回新的MAXID的值,
存储过程是这样设计的 首先读取 MAXID 然后 UPDATE MAXID+1
但是如果多用户同时取数据时会不会产生这样的后果
但是万一在我读取MAXID 和UPDATE 之间时间内 有其它用户UPDATE MAXID
那么这时我的存储过程将返回两个完全相同的MAXID 这个MAXID将用于其它表中做主键.
是不是使用锁定表能够解决这个问题?哪位最好给点小例子让我看看

...全文
86 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
enhydraboy 2003-08-26
  • 打赏
  • 举报
回复
如果想先select后update
需要把缺省的锁定机制设置为REPEATABLE READ。

我本人不太喜欢表级锁定,因为这种做法会大大降低并发性,而且这种应用需求更本不需要表级锁。
xiays 2003-08-26
  • 打赏
  • 举报
回复
谢谢
enhydraboy 2003-08-26
  • 打赏
  • 举报
回复
楼主的问题,解决起来其实很简单。
利用SQL Server缺省得锁定机制就可以了。通过事务,先+1再select,就可以保证并发性,并且大家拿到的序列号不会重复。
CREATE PROCEDURE dbo.sp_GetSequenceNo
(@SequenceName varchar(255),@SeqNo int output)
AS
BEGIN
BEGIN TRAN
UPDATE dbo.Sequence SET seq_curval=seq_curval+seq_step
WHERE seq_name=@SequenceName
IF @@error!=0
BEGIN
ROLLBACK tran
return 0
END
SELECT @SeqNo=seq_curval FROM dbo.Sequence
WHERE seq_name=@SequenceName
COMMIT TRAN
END
pengdali 2003-08-26
  • 打赏
  • 举报
回复
1 如何锁一个表的某一行


A 连接中执行

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

begin tran

select * from tablename with (rowlock) where id=3

waitfor delay '00:00:05'

commit tran

B连接中如果执行

update tablename set colname='10' where id=3 --则要等待5秒

update tablename set colname='10' where id<>3 --可立即执行

2 锁定数据库的一个表

SELECT * FROM table WITH (HOLDLOCK)


注意: 锁定数据库的一个表的区别

SELECT * FROM table WITH (HOLDLOCK)
其他事务可以读取表,但不能更新删除

SELECT * FROM table WITH (TABLOCKX)
其他事务不能读取表,更新和删除

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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