并发问题讨论
高并发效率极其低下,5分钟客户端全部接受反馈,数据库插入尚未执行完毕。
for (; i < 10000; i++) { Thread thread = new Thread(threadStart); thread.Start(); }
系统每6秒执行以下操作,做持久化。
// 作者: 不要理我 // 邮件: 869722304@qq.com(仅仅支持商业合作洽谈) // 创建时间: 2012-08-8 // 最后修改时间: 2012-08-11 // // 未经修改的文件版权属于原作者所有,但是你可以阅读,修改,调试。本项目不建议商用,不能确保稳定性。 // 同时由于项目Bug引起的一切问题,原作者概不负责。 // // 本项目所引用的所有类库,仍然遵循其原本的协议,不得侵害其版权。 // // 您一旦下载就视为您已经阅读此声明。 // // 您不可以移除项目中任何声明。 using CJCMS.Contracts.DTO.Vote; using CJCMS.Domain.Entity; using CJCMS.Domain.Service; using CJCMS.Framework.Logging; using CJCMS.Framework.Task; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; namespace CJCMS.Application { public class VoteTask : IBackgroundTask { public bool IsWorking { get; set; } //缓存投票数组 static Dictionary<string, VoteValueDTO> voteList = new Dictionary<string,VoteValueDTO>(); public VoteTask(bool workFlg) { IsWorking = true; } //加入新投票 public static void Add(string key, VoteValueDTO vote) { //加互斥锁 高并发效率不佳 此处犯愁 lock (voteList) { //判断是否重复投票 if (voteList.ContainsKey(key)) { throw new Exception("Do not re-vote."); } voteList.Add(key, vote); } } //投票持久化数据库,则内存中删除 public static void Remove(string key) { lock (voteList) { voteList.Remove(key); } } //守护函数 每6秒运行一次 public void DoWork() { try { VoteService service = new VoteService(); foreach (KeyValuePair<string, VoteValueDTO> voteValue in voteList) { try { //插入一张投票到数据库 表一行 无其他操作 service.DoVote1(AutoMapper.Mapper.Map<VoteValueDTO, VoteValue>(voteValue.Value)); //删除内存此投票 Remove(voteValue.Value.VoteItemId + voteValue.Value.Ip); } catch (Exception ee) { LogHelper.WriteLog(ee.Message); } } } catch (Exception ee) { LogHelper.WriteLog(ee.Message); } } } }
客户端投票执行的接口如下:
//vote public void DoVote(VoteValueDTO voteValue) { try { VoteService service = new VoteService(); //查询数据库此ip是否有过投票 if (!service.ExistVoteByIp(voteValue.VoteItemId, voteValue.Ip)) { //投票 VoteTask.Add(voteValue.VoteItemId + voteValue.Ip, voteValue); } else { throw new Exception("Do not re-vote."); } //service.DoVote(AutoMapper.Mapper.Map<VoteValueDTO, VoteValue>(voteValue)); } catch (Exception ee) { LogHelper.WriteLog(ee.Message); //throw new Exception("service bussy"); } }
目前由于数据库插入操作比较费时,队列入内存,每6秒将内存数据持久化。然并发入队列操作,和6秒的持久化操作会同时使用队列,则队列需互斥锁。效率低下。所以想问问大家策略,望大家赐教。