• 并发情况下临界值问题处理小记


    上周双11,客户要跟风做个问卷答题领爱奇艺会员的活动。

    客户那边和爱奇艺的合同是5000个会员,让我们做好并发控制,如果超过了我们要赔钱......

    我们这边的流程是先查询数据库记录条数,如果小于5000,则调用爱奇艺的接口,

    将返回数据与答题答案一起存在库中,如果大于5000,则只记录答题答案不调用

    爱奇艺的接口。

    由于公司基于数据库的查询有一套自己的方式,这里为了保证查询,调用爱奇艺,

    新增数据都在一个事物内,这里采用了JDBC的方式连接数据库,手动设置提交或者回滚。

    起初接到这个问题想通过单例模式来解决,后来因为客户要弄分布式服务就转换了思路,

    采用“悲观锁”来解决问题,即通过对数据库上锁的方式来解决。

    初步做法是

    select * from xxx for update //通过for update锁住该表

    //执行爱奇艺接口 insert xxxx //执行添加记录方法 commit() //提交事物

    然后模拟并发,我们发现(A为先执行的程序,B为后执行的程序):

    程序的执行顺序确实是按照我们预期的那样,待A commti之后 B才开始的查询,但是B 查询到的数据始终和 A查询到的条数相同。

    这点让我很费解,起初以为是jdbc预查询导致的,后面用普通的查询语句一样还是这种情况,于是我做了如下模拟:

    1):第一个用户进来调用for update语句查询

    2)另外开个客户端也调用这个语句

    3)此时显示正在执行,表示该表已经被第一个锁住,然后此时我在第一个锁住的客户端中添加了一条数据后提交

    4)再看刚才正在执行的窗口

    神奇的发现还是只有3条数据,没有刚才新增的数据。那么问题就是出在这里。

    于是这时决定在调用查询之前先将表锁住,锁住后在去查询,调用接口,插入数据,提交,通过先锁表来保证真正的查询的数据为数据库的真实数据。

    select * from xxx for update//通过for update锁住表
    
    select count(*) from xxx 
    
    //执行爱奇艺接口
    
    insert xxxx //执行添加记录方法
    
    commit() //提交事物

    后解决。

  • 相关阅读:
    改造我们的学习:有钱不会花,抱着金库抓瞎
    (转)我奋斗了18年才和你坐在一起喝咖啡
    初学者要知道的十件事
    [转]C#图像处理 (各种旋转、改变大小、柔化、锐化、雾化、底片、浮雕、黑白、滤镜效果)
    C#调用系统的复制、移动、删除文件对话框
    SQLite数据类型
    jquery禁用dropdownlist中某一项
    C# winform无标题窗体随意移动
    注册.NET Framework
    jQuery同步/异步调用后台方法
  • 原文地址:https://www.cnblogs.com/Onedayzk/p/7826797.html
Copyright © 2020-2023  润新知