併發問題討論

高併發效率極其低下,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秒的持久化操做會同時使用隊列,則隊列需互斥鎖。效率低下。因此想問問你們策略,望你們賜教。併發

相關文章
相關標籤/搜索