• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >ASP.NET > 《解剖PetShop》之三:PetShop数据访问层之消息处理

《解剖PetShop》之三:PetShop数据访问层之消息处理

作者:张逸 字体:[增加 减小] 来源:互联网 时间:2017-05-11

张逸通过本文主要向大家介绍了petshop,petshop是什么意思,petshop 6.0下载,petshop源码,petshop官网等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

三、PetShop数据访问层之消息处理

  在进行系统设计时,除了对安全、事务等问题给与足够的重视外,性能也是一个不可避免的问题所在,尤其是一个B/S结构的软件系统,必须充分地考虑访问量、数据流量、服务器负荷的问题。解决性能的瓶颈,除了对硬件系统进行升级外,软件设计的合理性尤为重要。

  在前面我曾提到,分层式结构设计可能会在一定程度上影响数据访问的性能,然而与它给设计人员带来的好处相比,几乎可以忽略。要提供整个系统的性能,还可以从数据库的优化着手,例如连接池的使用、建立索引、优化查询策略等等,例如在PetShop中就利用了数据库的Cache,对于数据量较大的订单数据,则利用分库的方式为其单独建立了Order和Inventory数据库。而在软件设计上,比较有用的方式是利用多线程与异步处理方式。

  在PetShop4.0中,使用了Microsoft Messaging Queue(MSMQ)技术来完成异步处理,利用消息队列临时存放要插入的数据,使得数据访问因为不需要访问数据库从而提供了访问性能,至于队列中的数据,则等待系统空闲的时候再进行处理,将其最终插入到数据库中。

  PetShop4.0中的消息处理,主要分为如下几部分:消息接口IMessaging、消息工厂MessagingFactory、MSMQ实现MSMQMessaging以及数据后台处理应用程序OrderProcessor。

  从模块化分上,PetShop自始自终地履行了“面向接口设计”的原则,将消息处理的接口与实现分开,并通过工厂模式封装消息实现对象的创建,以达到松散耦合的目的。

  由于在PetShop中仅对订单的处理使用了异步处理方式,因此在消息接口IMessaging中,仅定义了一个IOrder接口,其类图如下:
http://files.weikejianghu.com/file_images/article/201605/2016052710225415.gif
  在对消息接口的实现中,考虑到未来的扩展中会有其他的数据对象会使用MSMQ,因此定义了一个Queue的基类,实现消息Receive和Send的基本操作:

public virtual object Receive()
{
 try
 {
  using (Message message = queue.Receive(timeout, transactionType))
   return message;
 }
 catch (MessageQueueException mqex)
 {
  if (mqex.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
   throw new TimeoutException();
   throw;
 }
}
public virtual void Send(object msg)
{
  queue.Send(msg, transactionType);
}


</div>

  其中queue对象是System.Messaging.MessageQueue类型,作为存放数据的队列。MSMQ队列是一个可持久的队列,因此不必担心用户不间断地下订单会导致订单数据的丢失。在PetShopQueue设置了timeout值,OrderProcessor会根据timeout值定期扫描队列中的订单数据。

  MSMQMessaging模块中,Order对象实现了IMessaging模块中定义的接口IOrder,同时它还继承了基类PetShopQueue,其定义如下:

public class Order:PetShopQueue, PetShop.IMessaging.IOrder
 
  方法的实现代码如下:
public new OrderInfo Receive()
{
 // This method involves in distributed transaction and need Automatic Transaction type
 base.transactionType = MessageQueueTransactionType.Automatic;
 return (OrderInfo)((Message)base.Receive()).Body;
}

public OrderInfo Receive(int timeout)
{
 base.timeout = TimeSpan.FromSeconds(Convert.ToDouble(timeout));
 return Receive();
}

public void Send(OrderInfo orderMessage)
{
 // This method does not involve in distributed transaction and optimizes performance using Single type
 base.transactionType = MessageQueueTransactionType.Single;
 base.Send(orderMessage);
}

</div>

所以,最后的类图应该如下:

http://files.weikejianghu.com/file_images/article/201605/2016052710225416.gif

注意在Order类的Receive()方法中,是用new关键字而不是override关键字来重写其父类PetShopQueue的Receive()虚方法。因此,如果是实例化如下的对象,将会调用PetShopQueue的Receive()方法,而不是子类Order的Receive()方法:

PetShopQueue queue = new Order();
queue.Receive();
</div>

从设计上来看,由于PetShop采用“面向接口设计”的原则,如果我们要创建Order对象,应该采用如下的方式:

IOrder order = new Order();
order.Receive();
</div>

考虑到IOrder的实现有可能的变化,PetShop仍然利用了工厂模式,将IOrder对象的创建用专门的工厂模块进行了封装:
http://files.weikejianghu.com/file_images/article/201605/2016052710225417.gif

在类QueueAccess中,通过CreateOrder()方法利用反射技术创建正确的IOrder类型对象:

public static PetShop.IMessaging.IOrder CreateOrder()
{
 string className = path + ".Order";
 return PetShop.IMessaging.IOrder)Assembly.Load(path).CreateInstance(className);
}
</div>

path的值通过配置文件获取:

private static readonly string path = ConfigurationManager.AppSettings["OrderMessaging"];
</div>

而配置文件中,OrderMessaging的值设置如下:

<add key="OrderMessaging" value="PetShop.MSMQMessaging"/>
</div>

之所以利用工厂模式来负责对象的创建,是便于在业务层中对其调用,例如在BLL模块中OrderAsynchronous类:

public class OrderAsynchronous : IOrderStrategy
{  
 private static readonly PetShop.IMessaging.IOrder asynchOrder = PetShop.MessagingFactory.QueueAccess.CreateOrder();
 public void Insert(PetShop.Model.OrderInfo order)
 {
  asynchOrder.Send(order);
 }
}
</div>

  一旦IOrder接口的实现发生变化,这种实现方式就可以使得客户仅需要修改配置文件,而不需要修改代码,如此就可以避免程序集的重新编译和部署,使得系统能够灵活应对需求的改变。例如定义一个实现IOrder接口的SpecialOrder,则可以新增一个模块,如PetShop.SpecialMSMQMessaging,而类名则仍然为Order,那么此时我们仅需要修改配置文件中OrderMessaging的值即可:

<add key="OrderMessaging" value="PetShop.SpecialMSMQMessaging"/>
</div>

OrderProcessor是一个控制台应用程序,不过可以根据需求将其设计为Windows Service。它的目的就是接收消息队列中的订单数据,然后将其插入到Order和Inventory数据库中。它利用了多线程技术,以达到提高系统性能的目的。
  在OrderProcessor应用程序中,主函数Main用于控制线程,而核心的执行任务则由方法ProcessOrders()实现:

private static void ProcessOrders()
{
 // the transaction timeout should be long enough to handle all of orders in the batch
 TimeSpan tsTimeout = TimeSpan.FromSeconds(Convert.ToDouble(transactionTimeout * batchSize));

 Order order = new Order();
 while (true)
 {
  // queue timeout variables
  TimeSpan datetimeStarting = new TimeSpan(DateTime.Now.Ticks);
  double elapsedTime = 0;

  int processedItems = 0;

  ArrayList queueOrders = new ArrayList();

  using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required, tsTimeout))
  {
   // Receive the orders from the queue
   for (int j = 0; j < batchSize; j++)
   {
    try
    {
     //only receive more queued orders if there is enough time
     if ((elapsedTime + queueTimeout + transactionTimeout) < tsTimeout.TotalSeconds)
     {
      queueOrders.Add(order.ReceiveFromQueue(queueTimeout));
     }
     else
     {
      j = batchSize; // exit loop
     }

     //update elapsed time
     elapsedTime = new TimeSpan(DateTime.Now.Ticks).TotalSeconds - datetimeStarting.TotalSeconds;
    }
    catch (TimeoutException)
    {
     //exit loop because no more messages are waiting
     j = batchSize;
    }
   }
   //process the queued orders
   for (int k = 0; k < queueOrders.Count; k++)
   {
    order.Insert((OrderInfo)queueOrde



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 《解剖PetShop》之六:PetShop之表示层设计
  • 《解剖PetShop》之四:PetShop之ASP.NET缓存
  • 《解剖PetShop》之三:PetShop数据访问层之消息处理
  • 《解剖PetShop》之二:PetShop数据访问层数之据库访问设计
  • 《解剖PetShop》之一:PetShop的系统架构设计

相关文章

  • 2017-05-11asp.net保存网上图片到服务器的实例
  • 2017-05-11.NET中函数Main的使用技巧
  • 2017-05-11ASP.NET 5中使用AzureAD实现单点登录
  • 2017-05-11asp.net实现固定GridView标题栏的方法(冻结列功能)
  • 2018-08-20ADO.NET获取数据(DataSet)同时获取表的架构实例
  • 2017-05-11asp.net下定制日期输出格式的代码
  • 2017-05-11压缩aspx页面删除多余空格的两种方法
  • 2017-05-11ASP.NET 中 Button、LinkButton和ImageButton 三种控件的使用详解
  • 2017-05-11用ASP.Net实现文件的在线压缩和解压缩
  • 2018-08-20ASP.NET实现Hadoop增删改查的示例代码

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 解析利用wsdl.exe生成webservice代理类的详解
    • 不使用web服务(Service)实现文本框自动完成扩展
    • asp.net弹出窗口 返回值
    • RadioButtonList绑定图片及泛型Dictionary应用
    • .Net读取Excel 返回DataTable实例代码
    • asp.net 图标提取以及图标转换的实例代码
    • asp.net mvc-Controllerl篇 ControllerDescriptor
    • ASP.NET Core新建项目教程(3)
    • .net 添加Cookie的4种方法
    • Asp.Net HttpHandler 妙用

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有