[WCF Transaction] 1. 基本概念
WCF 支援分散式事務,也就是說事務可以跨越服務、程序、機器邊界,在多個服務和客戶端間存在。
Single service/single resource transaction
Distributed transactional service-oriented application
Transaction Binding
只有 TCP-、 IPC- 以及 WS-related 等 Binding 支援事務。預設情況下,這些 Binding 並不會參與事務,需要我們顯示將 TransactionFlow 屬性設定為 true 才行。
tcpBinding.TransactionFlow = true;
或
<netTcpBinding>
<binding name = "TransactionalTCP" transactionFlow = "true" />
</netTcpBinding>
</bindings>
TransactionFlow 並不會在 Metadata 中釋出,也就是說我們同樣需要手動設定客戶端 Binding 的 TransactionFlow 屬性。
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 預設就是可靠性,則無需再做調整。
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 環境。
tcpBinding.TransactionFlow = true;
tcpBinding.TransactionProtocol = TransactionProtocol.WSAtomicTransactionOctober2004;
或
<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)。
----------
圖片選自《Programming WCF Service》。