我们也来hold住--优化SQL SERVER锁的使用

     秒杀已经很不陌生了,秒杀对于我们程序员来说更多的是并发带来的思考,也许有天才考虑的是如何做秒杀器来横扫“秒杀江湖”。前日应邀来优化秒杀的sql。

  让我们来看看这秒杀的存储过程。(部分代码如下)

  

create   PROCEDURE   [ dbo ] . [ kill ]
    
@userid   nvarchar ( 64 ),
    
@killId   int
AS
BEGIN
    
BEGIN   TRAN
        
declare   @storage   int
        
-- 判断库存
         select   @storage = storage  from  killProduct  with (tablockx)  where  killID = @killId  
        
IF ( @@rowcount   =   0 )
        
BEGIN
            
COMMIT   TRAN
            
select   ' 没货 '  
            
return  
        
END
        
IF ( @storage   <=   0 )
        
BEGIN
            
COMMIT   TRAN
            
select   ' 没货 '  
            
return  
        
END
        
        
-- 继续判定秒杀是否结束
        ....
        
-- 判断userId是否已经参加过秒杀
        ....

 

  初看有如下几个问题:

  1.if else 太多,影响性能,由于sql server本身不善于运算,一个if 分支的性能损耗比clr中的if高出许多,所以建议多多在clr中进行此等判定,同时建议类似分页等,第一页单独写sql,不要走这一的if(pageIndex=1)的分支。

  2.TRAN 这东西上得太早了。干嘛这么猴急呢,也不来点前戏就直接上,太不懂情调了。怎么说呢,事物的粒度一定要把握好,不要把太多资源锁在事物里,事物粒度太大,势必影响到性能。

  3.with(tablockx) 这个固然是有必要,因为秒杀自有的特点就是并发大,是个男人都知道,一定要挺住那么几秒钟。问题就是你要lock整个表,还要独享,那你必须要打败其他人了,所以就意味着其他人都是牺牲品了(排它锁,锁住整个表,其他人连查询其他行的数据都得排队)。

  4.没事找事 如上两个if 您不觉得第一个没有存在的必要吗?

 

  好了,我也不得瑟了,下面贴一段如何hold住的代码吧。(修改后的部分代码)

 

         -- 直接进行更新,通过子查询确认用户是否有参加过秒杀
         -- 通过hold来确保此过程结束前没有其他用户更新此行,可读,rowlock是共享锁
         UPDATE   killProduct   WITH (ROWLOCK, HOLDLOCK ) SET  storage = storage - 1 , @storage = storage
         
WHERE  killID = @killId   AND  storage > 0   AND   ( SELECT   COUNT ( 0 FROM  KILLlIST(NOLOCK)  WHERE  USERID = @USERID ) = 0
         
         
IF ( @storage > 0 )
         
BEGIN
            
-- 秒杀成功
          END
         
ELSE
         
BEGIN
            
-- 失败
          END

 

holdlock,hold住此行数据(rowlock),直到整个事务结束。

此处可以将holdlock换成UPDLOCK来实现同样的效果。

秒杀你hold住了吗?您在处理这样的并发时又是如何hold住的呢?请大家分享之!

 

  

转载于:https://www.cnblogs.com/buaaboyi/archive/2011/08/30/2159860.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值