已经过事务处理的 MSMQ 绑定(转载)
https://msdn.microsoft.com/zh-cn/biztalk/ms751493
本示例演示如何使用消息队列 (MSMQ) 执行已经过事务处理的排队通信。
注意 |
|---|
|
本主题的末尾介绍了此示例的设置过程和生成说明。 |
在排队通信中,客户端使用队列与服务进行通信。 更确切地说,客户端向队列发送消息。 服务从队列接收消息。 因此,不必同时运行服务和客户端便可使用队列进行通信。
当事务用于发送和接收消息时,实际上有两个单独的事务。 当客户端在事务范围内发送消息时,事务相对于客户端和客户端队列管理器来说是本地事务。 当服务在事务范围内接收消息时,事务相对于服务和接收队列管理器来说是本地事务。 请务必牢记,客户端和服务不会参与同一个事务;实际上,它们在对队列执行操作(如发送和接收)时使用的是不同的事务。
在本示例中,客户端在事务范围内向服务发送一批消息。 然后,服务在服务定义的事务范围内接收发送到队列的消息。
服务协定为 IOrderProcessor,如下面的示例代码所示。 此接口定义了适合与队列一起使用的单向服务。
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface IOrderProcessor
{
[OperationContract(IsOneWay = true)]
void SubmitPurchaseOrder(PurchaseOrder po);
}
服务行为通过将 TransactionScopeRequired 设置为 true 来定义操作行为。 这可确保此方法所访问的任何资源管理器都使用相同的事务范围从队列中检索消息。 它还确保在方法引发异常的情况下,将消息返回到队列。 如果未设置操作行为,队列通道会创建一个从队列中读取消息的事务,并在调度前自动提交该事务,这样当操作失败时,消息将丢失。 对于服务操作而言,最常见的方案是在用于从队列中读取消息的事务中进行登记,如下面的代码中所示。
// This service class that implements the service contract.
// This added code writes output to the console window.
public class OrderProcessorService : IOrderProcessor
{
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void SubmitPurchaseOrder(PurchaseOrder po)
{
Orders.Add(po);
Console.WriteLine("Processing {0} ", po);
}
…
}
服务是自承载服务。 使用 MSMQ 传输时,必须提前创建所使用的队列。 可以手动或通过代码完成此操作。 在此示例中,该服务包含代码,以检查队列是否存在并在不存在时创建队列。 从配置文件中读取队列名称。 ServiceModel 元数据实用工具 (Svcutil.exe) 使用该基址来生成服务的代理。
// Host the service within this EXE console application.
public static void Main()
{
// Get the MSMQ queue name from appSettings in configuration.
string queueName = ConfigurationManager.AppSettings["queueName"];
// Create the transacted MSMQ queue if necessary.
if (!MessageQueue.Exists(queueName))
MessageQueue.Create(queueName, true);
// Create a ServiceHost for the OrderProcessorService type.
using (ServiceHost serviceHost = new ServiceHost(typeof(OrderProcessorService)))
{
// Open the ServiceHost to create listeners and start listening for messages.
serviceHost.Open();
// The service can now be accessed.
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
// Close the ServiceHost to shut down the service.
serviceHost.Close();
}
}
MSMQ 队列名称在配置文件的 appSettings 节中指定,如以下示例配置所示。
<appSettings>
<add key="queueName" value=".\private$\ServiceModelSamplesTransacted" />
</appSettings>
注意 |
|---|
|
队列名称为本地计算机使用圆点 (.),并在使用 System.Messaging 创建队列时在其路径中使用反斜杠分隔符。 Windows Communication Foundation (WCF) 终结点使用具有 net.msmq 方案的队列地址,使用“localhost”来表示本地计算机,并在其路径中使用正斜杠。 |
客户端创建事务范围。 与队列的通信发生在事务范围之内,从而可将该事务范围视为原子单元,其中所有消息均将发送到队列或者没有任何消息发送到队列。 通过在事务范围上调用 Complete 可以提交事务。
// Create a client.
OrderProcessorClient client = new OrderProcessorClient();
// Create the purchase order.
PurchaseOrder po = new PurchaseOrder();
po.CustomerId = "somecustomer.com";
po.PONumber = Guid.NewGuid().ToString();
PurchaseOrderLineItem lineItem1 = new PurchaseOrderLineItem();
lineItem1.ProductId = "Blue Widget";
lineItem1.Quantity = 54;
lineItem1.UnitCost = 29.99F;
PurchaseOrderLineItem lineItem2 = new PurchaseOrderLineItem();
lineItem2.ProductId = "Red Widget";
lineItem2.Quantity = 890;
lineItem2.UnitCost = 45.89F;
po.orderLineItems = new PurchaseOrderLineItem[2];
po.orderLineItems[0] = lineItem1;
po.orderLineItems[1] = lineItem2;
// Create a transaction scope.
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
// Make a queued call to submit the purchase order.
client.SubmitPurchaseOrder(po);
// Complete the transaction.
scope.Complete();
}
// Closing the client gracefully closes the connection and cleans up resources.
client.Close();
Console.WriteLine();
Console.WriteLine("Press <ENTER> to terminate client.");
Console.ReadLine();
若要验证事务正在运行,请按照下面的示例代码注释事务范围来修改客户端,重新生成解决方案并运行客户端。
//scope.Complete();
因为事务没有完成,所以消息未发送到队列。
运行示例时,客户端和服务活动将显示在服务和客户端控制台窗口中。 您可以看到服务从客户端接收消息。 在每个控制台窗口中按 Enter 可以关闭服务和客户端。 请注意:由于正在使用队列,因此不必同时启动和运行客户端和服务。 可以先运行客户端,再将其关闭,然后启动服务,这样服务仍然会收到客户端的消息。
The service is ready.
Press <ENTER> to terminate service.
Processing Purchase Order: 7b31ce51-ae7c-4def-9b8b-617e4288eafd
Customer: somecustomer.com
OrderDetails
Order LineItem: 54 of Blue Widget @unit price: $29.99
Order LineItem: 890 of Red Widget @unit price: $45.89
Total cost of this order: $42461.56
Order status: Pending
设置、生成和运行示例
如果先运行服务,则它将检查以确保队列存在。 如果队列不存在,则服务将创建一个队列。 可以先运行服务以创建队列或通过 MSMQ 队列管理器创建一个队列。 执行下面的步骤来在 Windows 2008 中创建队列。
在 Visual Studio 2012 中打开服务器管理器。
展开“功能”选项卡。
右击“私有消息队列”,然后选择“新建”和“专用队列”。
选中“事务性”框。
输入 ServiceModelSamplesTransacted 作为新队列的名称。
若要生成 C# 或 Visual Basic .NET 版本的解决方案,请按照 生成 Windows Communication Foundation 示例中的说明进行操作。
若要用单机配置或跨计算机配置来运行示例,请按照 运行 Windows Communication Foundation 示例中的说明进行操作。
默认情况下使用 NetMsmqBinding 启用传输安全。 对于 MSMQ 传输安全存在两个相关属性: 和 。 默认情况下,身份验证模式设置为 Windows,保护级别设置为 Sign。 为了使 MSMQ 提供身份验证和签名功能,MSMQ 必须是域的一部分,并且必须安装 MSMQ 的 Active Directory 集成选项。 如果在未满足这些条件的计算机上运行此示例,将会收到错误。
在加入到工作组或在没有 Active Directory 集成的计算机上运行示例
如果计算机不是域成员或尚未安装 Active Directory 集成,请将身份验证模式和保护级别设置为 None 以关闭传输安全性,如下面的示例配置代码所示。
<system.serviceModel>
<services>
<service name="Microsoft.ServiceModel.Samples.OrderProcessorService"
behaviorConfiguration="OrderProcessorServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/ServiceModelSamples/service"/>
</baseAddresses>
</host>
<!-- Define NetMsmqEndpoint. -->
<endpoint
address="net.msmq://localhost/private/ServiceModelSamplesTransacted"
binding="netMsmqBinding"
bindingConfiguration="Binding1"
contract="Microsoft.ServiceModel.Samples.IOrderProcessor" />
<!-- The mex endpoint is explosed at http://localhost:8000/ServiceModelSamples/service/mex. -->
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services> <bindings>
<netMsmqBinding>
<binding name="Binding1">
<security mode="None" />
</binding>
</netMsmqBinding>
</bindings> <behaviors>
<serviceBehaviors>
<behavior name="OrderProcessorServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
</behavior>
</serviceBehaviors>
</behaviors> </system.serviceModel>
确保在运行示例前更改服务器和客户端上的配置。
注意将 securitymode 设置为 None 等效于将 、 和 Message 安全设置为 None。
已经过事务处理的 MSMQ 绑定(转载)的更多相关文章
- 基于MSMQ绑定的WCF服务实现总结
一. 创建消息队列 1 1) 创建一个非事物性的私有队列 1 2)设置消息队列访问权限 2 二.创建WCF服务并绑定消息队列 4 1)创建HelloService服务 4 ...
- 实战WCF中net.tcp和net.msmq绑定协议
平时很少写博文的,以前都是转载其他园友的文章,这几天有时间就自己尝试写一些wcf相关的文章,希望能给有需要的人带来一点帮助吧,水平有限再加上初次动手,写得不好还请多多包含!废话不多说了直接进入正题. ...
- ASP.NET Core MVC 模型绑定 (转载)
ASP.NET Core MVC的Model Binding会将HTTP Request数据,以映射的方式对应到参数中.基本上跟ASP.NET MVC差不多,但能Binding的来源更多了一些.本篇将 ...
- .NET分布式事务处理总结【下】 - 包含MSMQ的分布式事务处理
转自:http://www.cnblogs.com/daxnet/archive/2011/03/15/1984995.html .NET直接提供对MSMQ的访问支持,只需要添加System.Mess ...
- 浩哥解析MyBatis源码(十二)——binding绑定模块之MapperRegisty
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6758456.html 1.回顾 之前解析了解析模块parsing,其实所谓的解析模块就是为 ...
- MyBatis源码解析(十二)——binding绑定模块之MapperRegisty
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6758456.html 1.回顾 之前解析了解析模块parsing,其实所谓的解析模块就是为 ...
- WCF(五) 深入理解绑定
适用于本机WCF-WCF交互性能最佳的绑定: 允许跨主机,但只能用于部署同一台主机上,不能访问命名管道 netNamePipeBinding总结 一 WCF与SOA SOA是一种通过为所有软件提供服务 ...
- Centos7网卡绑定的方法
温和的方式请参考:https://www.cnblogs.com/zzf0305/p/9594093.html 一:传统的bond方式(饭已验证)------------本种的绑定方式比较暴躁 (1) ...
- WCF 服务编程 - 常用绑定
WCF 定义了5中常用的绑定. 一. 绑定 1.基本绑定: 对应于BasicHttpBinding类.基本绑定能够将WCF服务公开为传统的ASMX Web服务,使得原客户端能够与新的服务协作.如果客 ...
随机推荐
- 谈谈SQL 语句的优化技术
https://blogs.msdn.microsoft.com/apgcdsd/2011/01/10/sql-1/ 一.引言 一个凸现在很多开发者或数据库管理员面前的问题是数据库系统的性能问题.性能 ...
- I Could Have Danced All Night
百老汇著名音乐剧<窈窕淑女(My Fair Lady)>中脍炙人口的经典歌曲. Bed, bed ,I couldn't go to bed床,床,我不能上床去 My head's too ...
- Beginning Scala study note(6) Scala Collections
Scala's object-oriented collections support mutable and immutable type hierarchies. Also support fun ...
- python 爬虫(二)
python 爬虫 Advanced HTML Parsing 1. 通过属性查找标签:基本上在每一个网站上都有stylesheets,针对于不同的标签会有不同的css类于之向对应在我们看到的标签可能 ...
- 网络神器Greasemonkey(油猴子)使用方法简介+脚本分享【转载】
推荐下,觉得这个方法有用, 今天艾薇百科来介绍一下功能强大的Greasemonkey,俗称"油猴子",Greasemonkey可以自由定制网页,实现你想要的各种功能.堪称" ...
- 转:Delphi的类与继承(VB与delphi比较)
既然已经做出了com程序用delphi来开发的决定,那当然就要对delphi进行一些深入的了解.有人说delphi是一个用控件堆砌起来的工具,和vb没什么两样:也有人说dephi实际上是面向过程的,他 ...
- 普林斯顿算法课第四周作业_8Puzzle
作业地址:http://coursera.cs.princeton.edu/algs4/assignments/8puzzle.html 作业难点: 1.如何求一个Puzzle的解? 根据作业提示,使 ...
- 25个 Git 进阶技巧
[ 原文] http://www.open-open.com/lib/view/open1431331496857.html 我已经使用git差不多18个月了,觉得自己对它应该已经非常了解.然后来自G ...
- mysql 数据库可以非本地访问
GRANT ALL PRIVILEGES ON 数据库名.* TO root@'%' IDENTIFIED BY '密码' WITH GRANT OPTION;
- 【原】iOS学习之应用之间的操作
关于应用之间的相互操作,小编一直觉得非常高大上,在一次面试中被面试官一顿暴虐,今天小编就决定学习一下!经过一顿度娘,找到一些博客,不过都比较凌乱,我就打算自己整理一下! 首先要说的是每一个APP都可以 ...