zoukankan      html  css  js  c++  java
  • 由一个投票算法引发的思考

    博主的APP最近又新加了一个小功能,每个员工都可以上传自己的工作照,其他员工可以点赞,规则是:每张工作照每个员工(除上传者外)每日可点赞一次。举个例子:

    现有注册员工ABCD四人,A上传工作照两张P1和P2,BCD三人每天可为P1、P2分别点赞一次

    博主略加思考,写了下面一段代码来实现:

     1         /// <summary>
     2         /// 投票
     3         /// </summary>
     4         /// <param name="id">被投票对象ID</param>
     5         /// <param name="up">赞OR踩</param>
     6         /// <param name="voterName">投票人</param>
     7         /// <param name="canVote">是否允许投票</param>
     8         /// <returns></returns>
     9         public int Vote(int id, bool up, string voterName, out bool canVote)
    10         {
    11             canVote = repo.RecordVote(voterName, id, timeService.Now);
    12             if (canVote)
    13             {
    14                 return repo.UpdateVoteCount(id, up ? 1 : -1);
    19             }
    20             return 0;
    21         }

    注:

    1.RecordVote()方法记录投票信息,UpdateVoteCount()方法执行投票,并返回当前被点赞数

    2.再来看看RecordVote()方法的实现:

     1         private static object voteLocker = new Object();
     2 
     3         public bool RecordVote(string voterName, int staffId, DateTime voteTime)
     4         {
     5             lock (voteLocker)
     6             {
     7                 for (; ; )
     8                 {
     9                     var voter = db.Voters.FirstOrDefault(t => t.VoterName == voterName && t.StaffId == staffId);
    10                     if (voter != null)
    11                     {
    12                         if (voter.VoteTime.Date == voteTime.Date)
    13                         {
    14                             return false;
    15                         }
    16                         voter.VoteTime = voteTime;
    17                     }
    18                     else
    19                     {
    20                         voter = new FVoter() { VoterName = voterName, StaffId = staffId, VoteTime = voteTime };
    21                         db.Voters.Add(voter);
    22                     }
    23                     try
    24                     {
    25                         db.SaveChanges();
    26                         return true;
    27                     }
    28                     catch (Exception)
    29                     {
    30                     }
    31                 }
    32             }
    33         }

    3.OK,再看看UpdateVoteCount()方法实现

     1         private static object locker = new Object();
     2 
     3         public int UpdateVoteCount(int staffId, int voteCountChange)
     4         {
     5             lock (locker)
     6             {
     7                 for (; ; )
     8                 {
     9                     var staff = db.Staffs.FirstOrDefault(i => i.Id == staffId);
    10                     staff.VoteCount += voteCountChange;
    12                     try
    13                     {
    14                         db.SaveChanges();
    15                         return staff.VoteCount;
    16                     }
    17                     catch (DbUpdateException)
    18                     {
    19                         Thread.Sleep(random.Next(1, 10));
    20                     }
    21                 }
    22             }
    23         }

    好嘛,这下写完了开始使用,也没啥问题。APP呢也没上线,没啥用户,就几个开发和公司内部的人点来点去...

     

    那么,问题来了。比如一个管理员录入员工信息的方法,基本需求是:管理员提前录入所有签约员工信息,员工注册系统时输入手机号即被识别为已签约员工,个人信息自动获取。那这个方法肯定也是需要加上lock的,因为我们会同时存在多个管理员录入信息,要保证不重复录入,只有加上lock...

    我想问的是:

    1.有木有哪位大神能简单的归纳一下什么样的上下文中需要加lock,需要做并发处理?是不是所有可能并发的方法都需要?

    2.管理员的操作算不算并发操作?系统目前允许同一个管理员账户在多端登录操作,那是不是管理员操作的所有方法都需要做并发控制?

    3.由2引申到员工用户与企业用户,如果我开放允许这些用户的账户在多端登录系统,是不是都算并发?

    4.再来随便挑一个方法,比如注册方法,用户名为邮箱,要求不重复,然而我的数据库字段并没有做唯一约束,是不是也得加上lock?因为是有可能同时很多用户用同一个邮箱注册的,或者客户端没写好,多次重复点击了注册按钮...

    5.那么我很忧心的是,是不是所有方法都成了可能被并发的方法?

    ...

    博主编程水平有限,团队也很小,感觉知识很难扩充。如果上述内容很白很菜(自己都这么觉得,感觉进了死胡同又绕不出来),请一笑了之,也欢迎指点一二,感激不尽。

     

    天天为项目忙碌,感觉自己的水平并没有提高,迷茫ing...请各位指点迷津

  • 相关阅读:
    JZOJ5954.【NOIP2018模拟11.5A组】走向巅峰
    JZOJ5956.【NOIP2018模拟11.7A组】easy LCA
    JZOJ5957.【NOIP2018模拟11.7A组】scarborough fair
    JZOJ5959【NOIP2018模拟11.8A组】铁路运输
    NOIP2018游记
    Pycharm 解释器的快捷键
    计算机编程语言初识
    计算机初识
    Python之如何修改运行的快捷键
    [USACO09NOV]硬币的游戏A Coin Game
  • 原文地址:https://www.cnblogs.com/csqb-511612371/p/4875371.html
Copyright © 2011-2022 走看看