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

设置、生成和运行示例

  1. 如果先运行服务,则它将检查以确保队列存在。 如果队列不存在,则服务将创建一个队列。 可以先运行服务以创建队列或通过 MSMQ 队列管理器创建一个队列。 执行下面的步骤来在 Windows 2008 中创建队列。

    1. 在 Visual Studio 2012 中打开服务器管理器。

    2. 展开“功能”选项卡。

    3. 右击“私有消息队列”,然后选择“新建”“专用队列”

    4. 选中“事务性”框。

    5. 输入 ServiceModelSamplesTransacted 作为新队列的名称。

  2. 若要生成 C# 或 Visual Basic .NET 版本的解决方案,请按照 生成 Windows Communication Foundation 示例中的说明进行操作。

  3. 若要用单机配置或跨计算机配置来运行示例,请按照 运行 Windows Communication Foundation 示例中的说明进行操作。

默认情况下使用 NetMsmqBinding 启用传输安全。 对于 MSMQ 传输安全存在两个相关属性: 和 。 默认情况下,身份验证模式设置为 Windows,保护级别设置为 Sign。 为了使 MSMQ 提供身份验证和签名功能,MSMQ 必须是域的一部分,并且必须安装 MSMQ 的 Active Directory 集成选项。 如果在未满足这些条件的计算机上运行此示例,将会收到错误。

在加入到工作组或在没有 Active Directory 集成的计算机上运行示例

  1. 如果计算机不是域成员或尚未安装 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>
  2. 确保在运行示例前更改服务器和客户端上的配置。

    注意

    securitymode 设置为 None 等效于将 、 和 Message 安全设置为 None

已经过事务处理的 MSMQ 绑定(转载)的更多相关文章

  1. 基于MSMQ绑定的WCF服务实现总结

    一. 创建消息队列    1 1) 创建一个非事物性的私有队列    1 2)设置消息队列访问权限    2 二.创建WCF服务并绑定消息队列    4 1)创建HelloService服务    4 ...

  2. 实战WCF中net.tcp和net.msmq绑定协议

    平时很少写博文的,以前都是转载其他园友的文章,这几天有时间就自己尝试写一些wcf相关的文章,希望能给有需要的人带来一点帮助吧,水平有限再加上初次动手,写得不好还请多多包含!废话不多说了直接进入正题. ...

  3. ASP.NET Core MVC 模型绑定 (转载)

    ASP.NET Core MVC的Model Binding会将HTTP Request数据,以映射的方式对应到参数中.基本上跟ASP.NET MVC差不多,但能Binding的来源更多了一些.本篇将 ...

  4. .NET分布式事务处理总结【下】 - 包含MSMQ的分布式事务处理

    转自:http://www.cnblogs.com/daxnet/archive/2011/03/15/1984995.html .NET直接提供对MSMQ的访问支持,只需要添加System.Mess ...

  5. 浩哥解析MyBatis源码(十二)——binding绑定模块之MapperRegisty

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6758456.html 1.回顾 之前解析了解析模块parsing,其实所谓的解析模块就是为 ...

  6. MyBatis源码解析(十二)——binding绑定模块之MapperRegisty

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6758456.html 1.回顾 之前解析了解析模块parsing,其实所谓的解析模块就是为 ...

  7. WCF(五) 深入理解绑定

    适用于本机WCF-WCF交互性能最佳的绑定: 允许跨主机,但只能用于部署同一台主机上,不能访问命名管道 netNamePipeBinding总结 一 WCF与SOA SOA是一种通过为所有软件提供服务 ...

  8. Centos7网卡绑定的方法

    温和的方式请参考:https://www.cnblogs.com/zzf0305/p/9594093.html 一:传统的bond方式(饭已验证)------------本种的绑定方式比较暴躁 (1) ...

  9. WCF 服务编程 - 常用绑定

    WCF  定义了5中常用的绑定. 一. 绑定 1.基本绑定: 对应于BasicHttpBinding类.基本绑定能够将WCF服务公开为传统的ASMX Web服务,使得原客户端能够与新的服务协作.如果客 ...

随机推荐

  1. 【用xocde5打包 在IOS7以下也能显示无默认gloss 效果 图解】

    图解,只需要这几个地方修改以下就好了,看不懂的话,请留言 完毕:记着clean 以下项目文件

  2. Java 反射调用动态方法

    package com.pigetest.util; import java.lang.reflect.Method; public class PrivateMethodTestHelper { p ...

  3. 产品经理 - 移动支付+Pos收单分析

    产品经理 - 移动支付+Pos收单分析

  4. tecplot 脚本文件

    一个简单的C++代码,可以生成tecplot的脚本文件,打开文件就能自动绘图.绘图过程是先把文件导入,然后镜像,最后生成一个动画,但是导入的文件名称要求是有规律的. /* ** This progra ...

  5. 【面试题】D

    一面: 1.介绍实习项目,负责那一部分: 2.C++的三大特性: 3.7层网络协议:应用层协议有哪些,TCP/IP属于哪一层,三次握手: 4.Linux: 4.1.查看进程: 4.2.vim文件与to ...

  6. 2016-1-29 图解HTTP(04)

    第7章 确保Web安全的HTTPS 在HTTP协议中有可能存在信息窃听或身份伪装等安全问题.使用HTTPS通信机制可以有效的防止这些问题. 7.1 HTTP的缺点 ● 通信使用明文(不加密),内容可能 ...

  7. Lua 排行榜更新

    排行榜: key:玩家名字,val:玩家的数值 local key1 = {"a1", "a2", "b1", "b2" ...

  8. ACM: FZU 2105 Digits Count - 位运算的线段树【黑科技福利】

     FZU 2105  Digits Count Time Limit:10000MS     Memory Limit:262144KB     64bit IO Format:%I64d & ...

  9. jsoup获取图片示例

    import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.Inp ...

  10. Dictionary Learning(字典学习、稀疏表示以及其他)

    第一部分 字典学习以及稀疏表示的概要 字典学习(Dictionary Learning)和稀疏表示(Sparse Representation)在学术界的正式称谓应该是稀疏字典学习(Sparse Di ...