asp.net多站点cache同步的一种解决方案

来源:互联网 发布:代申请淘宝达人大v 编辑:程序博客网 时间:2024/06/05 16:22

asp.net多站点cache同步解决方案

这段时间手上一个项目myproc,采用asp.net2.0和mssql2000开发.
项目在前台呈现为三个部分
销售网站 sale
收购站 vend
后台管理 admin
项目采用三层结构.共包括
sqlsererdal,model,bll,cache,uitility,sale,admin,vend 8个部分组成
解决方案结构参见图1(后来调整站点结构,将admin归到vend下面去了,所以图中是7个组成部分)

因为asp.net2.0中ms考滤安全性问题所以,不支付cache的跨站点共享(不知道是不是我弄错了,如果是支持的,那么请了解的朋友赐教),所以几个站点中存在cache同步问题.
比如 sale和vend都引用了cache命名空间中的game类, 当某一边更改了game信息后,另一边的cache需要同步. 针对这个问题,我用了以下的解决方案 :

 为了便于维护和扩充, 这里有一些配置文件,及配置访问方法,为了突出主题,我将配置文件略去.

看了上面的图,我想有的朋友已经知道我的意思了, 不错, 当某边站点更改了game信息后,利用db server的触发器,post一些数据到要更新cache的站点的触发cache更新的页面.

在要更新cache的表上建立触发器. 这里我以game表为例

CREATE TRIGGER updateCache_Game
ON Game
FOR INSERT,UPDATE
AS
 DECLARE @url0 VARCHAR(200),@Batch INT
 DECLARE @url1 VARCHAR(200)
 --默认为为批量
 SELECT @Batch=0
 IF (SELECT COUNT(*) FROM INSERTED)=1
  SELECT @Batch=GameID FROM INSERTED

 --url0 收购站 cacheupdate.url, url1 Sale.CacheUpdate.URL
 SELECT @url0=CASE WHEN About=0 THEN TouchOffURL ELSE @url0 END,
  @url1=CASE WHEN About=1 THEN TouchOffURL ELSE @url1 END
  FROM CacheUpdateConfig

 
 EXEC web_updateCache @url0,1,@Batch
 EXEC web_updateCache @url1,1,@Batch

创建触发页面的 存储过程
CREATE PROC web_updateCache
(
@url VARCHAR(200),
@CacheItemID INT,
@Batch INT
)
AS
 DECLARE @xmlhttp INT  
 DECLARE @Err  INT
 SET @url=@url+'?ItemID=' + RTRIM(@CacheItemID) + '&Batch=' + RTRIM(@Batch)
 EXEC @err = sp_OACreate "Microsoft.XMLHTTP",   @xmlhttp   OUT    
 EXEC @err = sp_OAMethod @xmlhttp,'Open',NULL,'POST',@url,'True'  
 EXEC @err = sp_OAMethod @xmlhttp,'Send',NULL,NULL
 EXEC @err = sp_OAMethod @xmlhttp,'Close',NULL


 INSERT UpdateCacheLog SELECT @url,@cacheItemID,@batch,@err --插条log记录. 可有可无,这里插这个,主要在调试时使用, 当然,以后可以用来做是否对方案进行改进的一个数据依具,如果因为网络或服务器原因,老是触发失败,就得考滤修改了

Sale.cacheUpdate.aspx.cs

   private void updateCache()
    {
        int itemid;
        int batch;

        if (Request["ItemID"] != null)
        {
            itemid = int.Parse(Request["ItemID"]);
        }
        else
        { return; }

        if (Request["Batch"] != null)
        {
            batch = int.Parse(Request["Batch"]);
        }
        else
        { return; }

 
        //其实这里可以不用switch, 因为 CacheType 是个enum类型,直接传itemid值调用即可,这里为了表述的明确一点.
 switch (itemid)
        {
 
            case 1:
                Cache.Utility.RefreshCache(.Cache.CacheType.Game,batch);

                break;
  //其它一些可能性略去
            case 6:
                Cache.Utility.RefreshCache(Cache.CacheType.SystemConfig,batch);
                break;
        }

    }