• Web应用程序并发问题处理的一点小经验


    在web应用中,一个账户,会有N多个涉及到数字的字段。比如一个账户的金额,积分等。这些字段就涉及到增减的情况。如果是在测试环境下,靠程序员或者测试手动点击。一般是发现不了问题。

    一旦上到正式环境下。有真实用户做操作了,就很容易出现莫名其妙的金额和流水记录不一致的情况。如果没有足够的经验,很难排查出问题。

    据我了解,业界一般用使用三种解决方案

    • 1.使用消息队列
    • 2.悲观锁
    • 3.乐观锁

    因为博主自身处于小公司,对于消息队列没有实际操作经验。所以本篇文章主要讨论后面两种。

    悲观锁

    从名字上看,就是认为一定会发生并发的可能性,从源头上杜绝数据错乱的情况。

    常见的处理方式:

    数据库加锁。如SQL server的RowLock和Mysql中的for update

    优点:程序没问题的情况下完全不会出现数据问题

    缺点:性能不太好,数据库锁是非常消耗资源的行为

    乐观锁

    乐观锁和悲观锁相反。认为不会有并发问题。只在提交修改的时候,去检查一下当前这条数据是否有修改的迹象。

    常见处理方式:

    在数据库中加入一个列。记录下当前修改的版本号。每次修改的时候,判断版本号是否和之前查询出的是否一致,如果一致的。修改成功,不一致,无法修改。需要重新加载一次查询数据,然后循环判断操作

    伪代码如下:

    ndex = 1  //约定重试次数
    while(true){
    selct id ,money ,version from table  //查询当前记录
    money+=1; //修改数据
    update table set money = money,version = (version+1) where id = @id and version = version //更新到数据库,判断是否更新成功
    if(update){
    break;
    }
    //
    
    index+=1;
    if(index>3){
    break;
    }
    
    }

    乐观锁优点: 可以实现无锁操作,性能会比悲观锁高很多

    乐观锁缺点:有脏读问题,而且查询次数会比悲观锁多几倍


    了解这两种方式,已经可以纵横各大中小型应用了。

     
     
  • 相关阅读:
    SqlServer:此数据库处于单用户模式,导致数据库无法删除的处理
    syscolumns表中所有字段的意思
    SQL数据库之变量
    Sqlserver常用的时间函数---GETDATE、GETUTCDATE、DATENAME
    判断游标是否存在的同时检测游标状态
    向已写好的多行插入sql语句中添加字段和值
    truncate和delete之间有什么区别
    javascript实现单例模式
    关于javascript中的 执行上下文和对象变量
    了解javascript中的this --实例篇
  • 原文地址:https://www.cnblogs.com/boxrice/p/11670560.html
Copyright © 2020-2023  润新知