微软消息队列
转至网络:
事务性消息传递发送和接收应用程序表示要在一个事务范围内发送或检索消息,这称为事务性消息传递。在事务范围之外发送或检索消息称为非事务性消息传递。仅当采用一种使所有任务(包括非消息队列操作)全部成功或全部失败的方式执行任务时,才使用事务性消息。
事务的特点体现在其 ACID(原子性、持续性、隔离性、持久性)属性:
原子性。原子性指事务的全部行为或无行为。当事务包含一系列操作时,所有操作将被作为一个单独的操作对待,要么成功完成,要么根本不执行。
持续性。事务将系统从一个有效状态转换到另外一个有效状态。
隔离性。同时执行的多个事务在执行过程中互不影响。在每个事务看来,其他的事务在其之前已执行或在其之后执行。
持久性。事务执行完毕,即使系统或网络发生故障,它们也一直起作用。
当使用事务性消息传递时,发送或接收应用程序将有机会提交事务(所有操作均成功)或中止事务(其中一个操作失败)从而使所有更改回滚。当中止事务时,所有操作将回滚到事务被调用的状态。
在事务内发送消息时,所有消息均按发送顺序一起发送或根本不发送。如果消息可传送,则消息队列将保证所有在事务内发送的消息都将一次性到达,并且按消息的发送顺序到达。当在事务内检索消息时,所有消息将从队列中删除或被放回到队列中的原始位置。请注意,事务性消息不能被发送到多播地址,而且在事务上下文中查看消息是不合理的。
在消息队列中,一个事务可包括多个发送和接收操作。然而,不能在单个事务内发送和接收同一消息。在事务包括发送多个消息的情况下,所有消息将按照消息的发送顺序传输(如果提交事务),或一条消息也不传输(如果中止事务)。如果多个消息被发送到同一队列,消息队列保证消息一次性到达目标队列而且按照它们在事务内的发送顺序到达。详细信息,请参阅将事务性消息发送给多个目标。
消息传递顺序
按照发送顺序传送的消息属于同一“消息流”。流中的每一条消息都带有一个“序列号”作为标识,还带有上一号码,它等于流中上一条消息的序列号。如果某消息的序列号等于另一消息的上一号码,则前者必须在后者被传送之前到达目标队列。流中的第一条消息所携带的上一号码总是为零。
同样,一个事务可包括从队列中删除多条消息。仅当事务提交时才从队列中删除消息;否则,消息将返回队列,随后在另一事务中被读取。
另外,消息队列保证在从同一计算机启动且到同一目标队列的连续事务内发送的消息将按照事务提交的顺序到达。而且,至于其他发送事务性消息的情况,每一则消息都将一次性到达(如果到达目标队列的话)。
事务性能
由于消息多次写到磁盘而且要求占用更多的计算机资源,因此事务性消息传递比非事务性消息传递慢。事务性消息只能被发送到本地计算机或远程计算机上的事务性队列(非事务性消息不能被发送到事务性队列)。当在事务内接收到消息时,只能从本地事务性队列对其进行检索。然而,可以从本地和远程队列事务性队列在非事务性操作中对消息进行检索。
一般情况下,有如下两种方法实现事务性消息传递:
外部事务
内部事务
外部事务
如果是资源而不是消息队列能提供的内容需要成为事务处理的一部分,则使用外部事务处理。外部事务由 Microsoft 分布式事务协调器 (DTC) 进行协调,Microsoft 分布式事务协调器现在是“组件服务”(之前称为“事务服务器”)的一部分。消息队列则作为 DTC 控制下的“资源管理器”提供服务。通过使用 DTC 作为消息队列的“事务管理器”,可执行基于事务的应用程序,从而确保所有操作全部成功或全部失败。例如,消息队列应用程序可以发送消息,并更新相同事务处理中的数据库。DTC 可确保以上两种操作全部成功(两种操作均被提交)或一个操作也不执行(两种操作均被中止)。在 Windows Server 2003 家族操作系统的安装过程中,DTC 将自动安装以便进行本地事务处理。要在网络中启用消息队列事务所需的网络 DTC,请参阅启用网络 DTC 访问。
有关 DTC 的详细信息,请参阅“组件服务”帮助文件中的使用组件服务。
可以使用外部事务处理发送或接收作为 COM 兼容资源操作一部分的消息,并发送或接收作为单独事务处理一部分的多个消息。
COM+ 事务
当您的应用程序在 COM+(组件服务)环境下运行时,消息队列可通过使用当前可用的 COM+ 事务对象在 COM+ 事务内发送和接收消息。消息队列、COM+(组件服务)和 DTC 为该类型事务协同工作。
XA - 兼容事务
消息队列可在具有 XA - 兼容的事务管理器的事务系统中工作。因此,DTC 作为事务过程监视器被使用而消息队列作为资源管理器被使用。
内部事务
由于开销较少,内部事务处理比由 DTC 协调的外部事务处理快得多。如果不需要在消息队列操作与涉及要求使用 DTC 的外部资源的操作之间进行协调,请使用内部事务。消息队列只提供支持本身作为资源管理器的事务协调器。
您可以使用内部事务执行以下操作:
确保消息只传送一次(称为“一次性传送”)。
确保从一台计算机发送到其他计算机的全部消息都按顺序传送(称为“按顺序传送”)。
使用确认消息,确认事务成功(消息接收到)。也可以使用确认消息来确认该消息是否到达目标队列(或从目标队列删除)。
有一种特定类型的内部事务,由消息队列在发送单个消息时提供:
单个消息事务
当发送单个消息时,消息队列提供单个消息事务,该单个消息事务隐含地使用消息队列内部事务,并包含单个消息上所执行的单个操作。单个消息事务可用于要求确保一次性传送发送到事务性队列的单个消息。单个消息事务为发送消息提供了所有事务类型的最佳性能。除一次性传送之外,单个消息事务快于外部事务。
有关事务类型的详细信息,请参考“消息队列软件开发工具包 (SDK)”。有关访问消息队列 SDK 的信息,请参阅 Microsoft 平台软件开发工具包。
事务性 HTTP 消息的顺序确认消息
事务性消息只传输一次,其传输顺序与发送时相同。当事务性消息经由 HTTP 从企业内部网络发送到 Internet 时,发送方顺序队列的内部名称必须通过映射翻译成逻辑地址,以便将顺序确认消息从位于发送方企业外部的接收计算机定向回发送方的顺序队列。详细信息,请参阅存储和转发服务器。
将事务性消息发送给多个目标通讯组列表和多元素格式名都支持事务性消息。当在一个事务内将消息发送到通讯组列表或多元素格式名时,会将消息的副本发送到每个可用的传出队列中。如果在将消息发送到所有传出队列的过程中出现故障时,将中止整个事务。通讯组列表或多元素格式名可以引用事务目标队列和非事务目标队列的混合。当事务性消息发送到该混合目标时,允许将此消息发送到本地或远程计算机上的所有事务目标队列和非事务目标队列中。但是,当消息到达非事务性队列时,此消息将被拒绝,并被传递到非事务性队列所在计算机上的事务性死信队列中进行存储,而且将有一条否定的确认消息发送到在原始消息中指定的管理队列,它表明事务性消息已发送到非事务性队列中。
正好传递一次和按顺序传递
消息队列保证事务性消息按顺序传递并正好传递一次。正好一次按顺序传递 (EOD) 协议是个端对端协议,它保证消息不进行复制并按顺序传递。为了获得这种保证,发送方可向每一条消息附加信息,这些附加信息允许接收方除去重复的和顺序不正确的消息。相互之间具有顺序关系的所有消息都被视为在同一“消息流”中。流中的每条消息都携带一个用于标识流中消息的序列号,并携带一个“上一号码”,用于标识在同一消息流中的前一消息。通常,流中的第一条消息所携带的上一号码为零。
每个接收方都筛选最新到达的消息,并且只接受那些按顺序到达的而且不是重复的消息。为了实现这项功能,接收方将使用附加到该消息的序列号和上一号码。接收方需要跟踪在每个消息流中最后收到的消息的序列号,而不需要保持消息历史记录或很大的数据库。通过将接收到的最后一条消息的序列号发送回发送方,接收方可进行确认。这样发送方就可知道接收方已接受到包括确认消息在内的所有消息。
发送消息
发送方使用单调增加的序列号标记每条消息,并且使用上一号码将消息链接到上一条消息。如果消息流中不存在上一条消息,那么发送方就将上一号码字段置为零。这样就能确保接收方收到消息。从消息流中删除在发送方丢弃的消息(例如,在超时结束前接收消息时),并将下一条消息链接到所删除的消息的前一条消息。
从接收方返回“顺序确认”之前,发送方需要不断重新发送同一消息。此确认携带了一个序列号,表明此号码和此号码之前的所有消息已经按顺序正好安全到达目标一次。因此,发送方可以安全地丢弃该指定序列号消息以及该序列号之前的所有消息。
要解决接收方不能恢复其数据库(该数据库是给定消息流的最后一个已接受的消息序列号)这一故障,发送方必须将队列中第一条消息的上一号码值指派为零。另一方面,将序列号附加到消息上后,就无法再对其进行更改。
接收消息
接收方跟踪每个消息流中最后接受的消息的序列号。接收方使用该号码筛选出到达的消息,而且只接受那些按顺序传递且不重复的消息。接收方将每个新消息流的最后一个号码初始化为零。接收方必须实现的最简单的算法如下所示:
if(message.sequence <= last_accepted_sequence)
{
拒绝消息
}
if(message.previous > last_accepted_sequence)
{
拒绝消息
}
接受消息
last_accepted_sequence = message.sequence;
有时在创建了新的消息流后,接收方会发送包含最后一个接受的序列号的“顺序确认”。此确认通知发送方,目标已经接受消息流中指定序列号和指定序列号以前的所有消息。接收方不断为活动的消息流发送这些确认;此时,即使没有接受消息流的消息,其消息依然持续到达。
接收方将这些“顺序确认”发送到传入消息所指定的确认返回地址。同一消息流中的所有消息必须具有相同的确认返回地址。
建议确认消息的服务质量尽可能轻量,因为接收方将保持连续生成确认(最后一个序列号)的状态。
有关在事务内发送消息的详细信息,请参阅事务性消息传递。
有关将事务性消息发送到通讯组列表的详细信息,请参阅通讯组列表。
有关将事务性消息发送到多元素格式名的详细信息,请参阅多元素格式名。
http://www.cnblogs.com/rickie/archive/2004/11/16/64345.aspx
1, 为了避免存放消息队列的计算机重新启动而丢失消息,可以通过设置消息对象的Recoverable属性为true,在消息传递过程中将消息保存到磁盘上来保证消息的传递,默认为false。
2, 可以使用Transactional Message Queues,Message are durable – persisted to disk。