由一个投票算法引起的思考

博主的APP最近又新加了一个小功能,每一个员工均可以上传本身的工做照,其余员工能够点赞,规则是:每张工做照每一个员工(除上传者外)每日可点赞一次。举个例子:数据库

现有注册员工ABCD四人,A上传工做照两张P1和P2,BCD三人天天可为P一、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         }

注:dom

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

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

 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呢也没上线,没啥用户,就几个开发和公司内部的人点来点去...blog

 

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

我想问的是:string

1.有木有哪位大神能简单的概括一下什么样的上下文中须要加lock,须要作并发处理?是否是全部可能并发的方法都须要?

2.管理员的操做算不算并发操做?系统目前容许同一个管理员帐户在多端登陆操做,那是否是管理员操做的全部方法都须要作并发控制?

3.由2引伸到员工用户与企业用户,若是我开放容许这些用户的帐户在多端登陆系统,是否是都算并发?

4.再来随便挑一个方法,好比注册方法,用户名为邮箱,要求不重复,然而个人数据库字段并无作惟一约束,是否是也得加上lock?由于是有可能同时不少用户用同一个邮箱注册的,或者客户端没写好,屡次重复点击了注册按钮...

5.那么我很忧心的是,是否是全部方法都成了可能被并发的方法?

...

博主编程水平有限,团队也很小,感受知识很难扩充。若是上述内容很白很菜(本身都这么以为,感受进了死胡同又绕不出来),请一笑了之,也欢迎指点一二,感激涕零。

 

每天为项目忙碌,感受本身的水平并无提升,迷茫ing...请各位指点迷津

相关文章
相关标签/搜索