zoukankan      html  css  js  c++  java
  • 我们也来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(0FROM KILLlIST(NOLOCK) WHERE USERID=@USERID)=0
             
             
    IF(@storage>0)
             
    BEGIN
                
    --秒杀成功
             END
             
    ELSE
             
    BEGIN
                
    --失败
             END

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

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

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

      

  • 相关阅读:
    6 完全平方数相关
    5 三位数,每个位置不同
    Neo4j Admin Import 导入多个node和relationship
    Rust所有权
    Rust 多态
    Rust 泛型
    Rust trait
    Rust模块化
    Spring Cloud(Dalston.SR1)
    git 速度慢问题解决
  • 原文地址:https://www.cnblogs.com/buaaboyi/p/2159860.html
Copyright © 2011-2022 走看看