日期:2014-05-18  浏览次数:20560 次

如何加锁呢?
SQL code
ALTER PROCEDURE [dbo].[ProResultgoodsID]
@ID int output
AS
BEGIN TRANSACTION
select top 1 @ID=ID from goods WITH (rowlock)  where UploadState is null
set @ID=isnull(@ID,0)
update goods WITH (rowlock) set UploadState='正在上传' where ID=@ID
COMMIT TRANSACTION



goods 表里有30万条记录,数据库文件大小为900M

我用5个线程同时不停的执行上面的存储过程,发现取出的ID有很多是重复的

如果用 WITH (TABLOCKX) 可以取出不重复的ID,但是执行存储过程是速度会很缓慢.goods 

我希望能实现的效果是:取出的ID值不重复.

------解决方案--------------------
SQL code
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) 
其他事务不能读取表,更新和删除

------解决方案--------------------
提高隔离级别
------解决方案--------------------
如果将事务隔离级别设置为 SERIALIZABLE,并且在 SELECT 语句中使用表级锁定提示 NOLOCK,则键范围锁通常用于维护不采用可串行事务
SQL code

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE --加上这一句
BEGIN TRANSACTION

------解决方案--------------------
性能和解决并发问题不可得兼,选一个适合你的