并发问题讨论

高并发效率极其低下,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秒的持久化操作会同时使用队列,则队列需互斥锁。效率低下。所以想问问大家策略,望大家赐教。

 

posted @ 2013-09-14 16:40  不要理我  阅读(479)  评论(0编辑  收藏  举报