IOneWayAsync vs IOneWayAsyncTxn - Bug?

Greetings all,

I've noticed that when using the BAM R2 interceptors with WCF adapters, the Out of the Box implementation of IOneWayAsync and IOneWayAsyncTxn seem to be the exact same interfaces.

Ex:

[ServiceContract(Namespace="http://www.microsoft.com/biztalk/2006/r2/wcf-adapter")]
public interface IOneWayAsync
{
// Methods
[OperationContract(AsyncPattern=true, IsOneWay=true, Action="*")]
IAsyncResult BeginOneWayMethod(Message message, AsyncCallback callback, object state);
[OperationContract(IsOneWay=true, Action="BizTalkSubmit")]
void BizTalkSubmit(Message message);
void EndOneWayMethod(IAsyncResult result);
}


[ServiceContract(Namespace="http://www.microsoft.com/biztalk/2006/r2/wcf-adapter")]
public interface IOneWayAsyncTxn
{
// Methods
[OperationContract(AsyncPattern=true, IsOneWay=true, Action="*")]
IAsyncResult BeginOneWayMethod(Message message, AsyncCallback callback, object state);
[OperationContract(IsOneWay=true, Action="BizTalkSubmit")]
void BizTalkSubmit(Message message);
void EndOneWayMethod(IAsyncResult result);
}

Where the TwoWay version of these makes it obviously clear that the xxxTXN version must have a Transaction flowed into its context, such as the following:

[ServiceContract(Namespace="http://www.microsoft.com/biztalk/2006/r2/wcf-adapter")]
public interface ITwoWayAsyncVoid
{
// Methods
[OperationContract(AsyncPattern=true, IsOneWay=false, Action="*", ReplyAction="*")]
IAsyncResult BeginTwoWayMethod(Message message, AsyncCallback callback, object state);
[OperationContract(IsOneWay=false, Action="BizTalkSubmit")]
void BizTalkSubmit(Message message);
void EndTwoWayMethod(IAsyncResult result);
}


[ServiceContract(Namespace="http://www.microsoft.com/biztalk/2006/r2/wcf-adapter")]
public interface ITwoWayAsyncVoidTxn
{
// Methods
[TransactionFlow(TransactionFlowOption.Mandatory), OperationContract(AsyncPattern=true, IsOneWay=false, Action="*", ReplyAction="*")]
IAsyncResult BeginTwoWayMethod(Message message, AsyncCallback callback, object state);
[OperationContract(IsOneWay=false, Action="BizTalkSubmit"),TransactionFlow(TransactionFlowOption.Mandatory)]
void BizTalkSubmit(Message message);
void EndTwoWayMethod(IAsyncResult result);
}

Shouldn't the IOneWayAsyncTxn also do the same... such as:

[ServiceContract(Namespace="http://www.microsoft.com/biztalk/2006/r2/wcf-adapter")]
public interface IOneWayAsyncTxn
{
// Methods
[OperationContract(AsyncPattern=true, IsOneWay=true?, Action="*"), TransactionFlow(TransactionFlowOption.Mandatory)]
IAsyncResult BeginOneWayMethod(Message message, AsyncCallback callback, object state);
[OperationContract(IsOneWay=true?, Action="BizTalkSubmit") TransactionFlow(TransactionFlowOption.Mandatory)]
void BizTalkSubmit(Message message);
void EndOneWayMethod(IAsyncResult result);
}

Is this a bug? Or more an architectural decision when dealing with WCF transactions? Also, is the above event possible considering that a transaction would need to send a Commit/Abort back, thus it wouldn't really be IsOneWay=true but rather IsOneWay=false, which effectively makes it the same as a ITwoWayAsyncVoidTxn?

-Thinking Out Loud (TOL)

-Dwight


[4478 byte] By [DwightGoins] at [2008-2-15]
# 1

Dwight - taking the issues one at a time:

1) IsOneWay - none of the BizTalk WCF Adapters do true one-way Operations, unless you are using an MSMQ binding . In a true one-way operation a sender sends a message to a receiver and isn't notified of the result either way. This allows the client to get back a soap fault if an exception happens. So all WCF receive location use the ITwoWay* interfaces unless it is MSMQ - in which case it uses the IOneWay* interfaces.

2) In the case of a true one-way Operation - you can't flow a client transaction using any protocol. If there is no way to communicate back to the client - there isn't any way to enable a transactional protocol. So having a TransactionFlow attribute on the operation with IsOneWay==true wouldn't make any sense - because the information in the operationcontract become part of the policy of the service - handing that back to a one-way client wouldn't be logical.

3) IOneWayAsyncTxn - it doesn't force the transaction to be flowed from the client (see #2 for why that doesn't make sense) - but when MSMQ is used - the service class that implements IOneWayAsyncTxn uses OperationBehavior to cause a transaction to be flowed into the method by the WCF runtime - so the read from MSMQ can be wrapped in a transaction.

So the difference is in the implementation not in the servicecontract where having a difference really wouldn't matter since having a transactional policy with a oneway operation doesn't make sense. In fact if you try to configure a service endpoint using the ServiceContract definition you proposed above you get an error from WCF:

"The one-way operation 'MyOperation1' on ServiceContract 'IMyService' is configured for transaction flow. Transactions cannot be flowed over one-way operations."

JonFlanders at 2007-10-3 > top of Msdn Tech,BizTalk Server,BizTalk Interceptors...
# 2

Jon,

Thanks for answering, and validating my assumptions.

So how can I get down with the Superstar? (http://www.masteringbiztalk.com/blogs/jon/PermaLink,guid,0d8c164f-9a60-4f3e-ae7f-c1d3bd51d0ba.aspx)

DwightGoins at 2007-10-3 > top of Msdn Tech,BizTalk Server,BizTalk Interceptors...