惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Announcements
Recent Announcements
雷峰网
雷峰网
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Hugging Face - Blog
Hugging Face - Blog
博客园 - 司徒正美
人人都是产品经理
人人都是产品经理
博客园 - 【当耐特】
量子位
有赞技术团队
有赞技术团队
博客园 - 三生石上(FineUI控件)
博客园 - Franky
M
MIT News - Artificial intelligence
U
Unit 42
Last Week in AI
Last Week in AI
酷 壳 – CoolShell
酷 壳 – CoolShell
The Cloudflare Blog
J
Java Code Geeks
V
Visual Studio Blog
Engineering at Meta
Engineering at Meta
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
MyScale Blog
MyScale Blog
T
Tailwind CSS Blog
T
The Blog of Author Tim Ferriss
V
V2EX

博客园 - 黑羽飘舞

挥别虎年,迎来兔年 评论:B2Cer,其实您既不电子,也不商务 整理思路重新开始,一段乱七八糟的“电子商务创业”经历。--工作有风险,选公司要谨慎 什么是电子商务的核心竞争力 Subtext分析3-Subtext.Akismet [转]序列化与反序列化,及Json序列化反序列化 [转]JSON序列化与反序列化 [转]WCF一个Host实现多契约服务 抽象类,接口,委托与事件 Subtext分析2-Subtext.BlogML Subtext分析1-前言架构 博客园的管理团队都在做什么,博客园是个大杂烩么? 项目那点儿事---山寨篇(注释不是程序员的负担) 我的2008,感谢2008,挥别2008 文档知多少---走出软件作坊:三五个人十来条枪 如何成为开发正规军(二十五)[转] 葵花点穴手 定---走出软件作坊:三五个人十来条枪 如何成为开发正规军(二十四)[转] 八部众---走出软件作坊:三五个人十来条枪 如何成为开发正规军(二十三)[转] 波、波、波---走出软件作坊:三五个人十来条枪 如何成为开发正规军(二十二)[转] 我要飞的更高---走出软件作坊:三五个人十来条枪 如何成为开发正规军(二十一)[转]
[转]WCF分布式事务
黑羽飘舞 · 2010-05-23 · via 博客园 - 黑羽飘舞

WCF 支持分布式事务,也就是说事务可以跨越服务、进程、机器边界,在多个服务和客户端间存在。

Single service/single resource transaction

uploads/200705/02_105023_wcftrans1.gif

Distributed transactional service-oriented application

uploads/200705/02_105028_wcftrans2.gif

Transaction Binding

只有 TCP-、 IPC- 以及 WS-related 等 Binding 支持事务。缺省情况下,这些 Binding 并不会参与事务,需要我们显示将 TransactionFlow 属性设置为 true 才行。

NetTcpBinding tcpBinding = new NetTcpBinding( );
tcpBinding.TransactionFlow 
= true;

<bindings>
  
<netTcpBinding>
    
<binding name = "TransactionalTCP" transactionFlow = "true" />
  
</netTcpBinding>
</bindings>

TransactionFlow 并不会在 Metadata 中发布,也就是说我们同样需要手动设置客户端 Binding 的 TransactionFlow 属性。

代码

WSHttpBinding binding = new WSHttpBinding();
binding.TransactionFlow 
= true;

ChannelFactory

<IContract> factory = new ChannelFactory<IContract>(binding,  "http://localhost:8080/myservice");
IContract client 
= factory.CreateChannel();
using (client as IDisposable)
{
  
using (TransactionScope scope = new TransactionScope())
  {
    client.Test();
    scope.Complete();
  }

启用可靠性(Reliability)通讯有助于减少事务失败的可能性,如果使用 NetTcpBinding、WSHttpBinding,建议做如下设置,以便启用可靠性传输。而 NetNamedPipeBinding 和 WSDualHttpBinding 默认就是可靠性,则无需再做调整。

NetTcpBinding binding = new NetTcpBinding();
binding.ReliableSession.Enabled 
= true;

Transaction Protocols

WCF 使用不同的事务管理协议来控制事务执行范围(execution scope)。

  • Lightweight: 仅能在同一程序域的上下文中传递事务,无法跨越程序域和服务边界。只能在服务内部或外部适用,同时它也是性能最好的一种协议。不过这种协议似乎没什么用处,因为 WCF Framework 中没有任何一种 Binding 支持此协议。
  • OleTx: 允许事务跨越程序域、进程或机器边界。使用 RPC 调用,采取 Windows 专用二进制格式。无法跨越防火墙,也不能和其他异种平台进行整合。多用于 Windows 体系的 Intranet 环境。
  • WS-Atomic(WSAT): 和 OleTx 相似,同样允许事务跨越程序域、进程或机器边界。和 OleTx 不同,WSAT 是一种工业标准,采取 HTTP 协议,TEXT 编码,可以跨越防火墙。虽然 WSAT 也能用于 Intranet,但多数时候它用于 Internet 环境。

NetTcpBinding tcpBinding = new NetTcpBinding( );
tcpBinding.TransactionFlow 
= true;
tcpBinding.TransactionProtocol 
= TransactionProtocol.WSAtomicTransactionOctober2004;

代码

<bindings>
  
<netTcpBinding>
    
<binding name = "TransactionalTCP"
      transactionFlow 
= "true"
      transactionProtocol 
= "WSAtomicTransactionOctober2004"
      
/>
  
</netTcpBinding>
</bindings>

Transactional Service

除了开启 Binding 的事务支持外,我们还必须通过 TransactionFlow 和 TransactionScopeRequired 来控制服务是否参与和使用事务。

TransactionFlowAttribute 只能用于服务方法(Operation/Method)上,它允许我们进行不同的事务参与设置。有一点要注意,我们不能为 IsOneWay=true 的服务设置事务支持。

  • TransactionFlowOption.NotAllowed: 不参与任何事务。(默认值)
  • TransactionFlowOption.Allowed: 允许参与事务。也就是说,如果调用方(客户端)和服务Binding启用了事务,则参与。
  • TransactionFlowOption.Mandatory: 强制启用事务。调用方(客户端)和服务 Binding 必须启用事务才能调用本服务。

"TransactionScopeRequired=true" 指示服务方法使用环境事务(ambient transaction)。

代码

[ServiceContract]
public interface IService
{
  [OperationContract]
  [TransactionFlow(TransactionFlowOption.Allowed)]
  
void Test();
}
public class Service : IService 
{
  [OperationBehavior(TransactionScopeRequired
=true)]
  
public void Test()
  {
    Transaction transaction 
= Transaction.Current;
    Debug.Assert(transaction 
== null);
  }
}

Transaction modes

我们可以将事务分为三种类型,分别是 Client/Service transaction、Client transaction、Service transaction。

1. Client/Service transaction,最常见的一种事务模型,通常由客户端或服务本身启用一个事务。

设置步骤:
(1) 选择一个支持事务的Binding,设置 TransactionFlow = true。
(2) 设置 TransactionFlow(TransactionFlowOption.Allowed)。
(3) 设置 OperationBehavior(TransactionScopeRequired=true)。

2. Client transaction,强制服务必须参与事务,而且必须是客户端启用事务。

设置步骤:
(1) 选择一个支持事务的Binding,设置 TransactionFlow = true。
(2) 设置 TransactionFlow(TransactionFlowOption.Mandatory)。
(3) 设置 OperationBehavior(TransactionScopeRequired=true)。

3. Service transaction,服务必须启用一个根事务,且不参与任何外部事务。

设置步骤:
(1) 选择任何一种Binding,设置 TransactionFlow = false(默认)。
(2) 设置 TransactionFlow(TransactionFlowOption.NotAllowed)。
(3) 设置 OperationBehavior(TransactionScopeRequired=true)。