WCF, MSMQ and independent transactions on 2 queues





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







1















I have built a WCF service that processes an MSMQ, let's call the service QueueService. The Contract looks like this:



// Each call to the service will be dispatched separately, not grouped into sessions.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class QueueServiceContract : IQueueServiceContract
{
[OperationBehavior(TransactionScopeRequired = true)]
public void QueueItems(List<Item> items) // really should be called 'HandleQueueItems
{
// Early in the processing I do:
Transaction qTransaction = Transaction.Current;
...
// I then check if the destination database is available.
if(DB.IsAvailable)
... process the data
else
qTransaction.Rollback;
...
}


IQueueServiceContract looks like this:



// The contract will be session-less.  Each post to the queue from the client will create a single message on the queue.
[ServiceContract(SessionMode = SessionMode.NotAllowed, Namespace = "MyWebService")]
public interface IQueueServiceContract
{
[OperationContract(IsOneWay = true)]
void QueueItems(List<Item> items);
}


Relevant parts of the App.config for the queue service look like this.



<services>
<service name="QueueService.QueueServiceContract">
<endpoint address="net.msmq://localhost/private/MyQueueServiceQueue" binding="netMsmqBinding" contract="QueueService.IQueueServiceContract">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
...
<netMsmqBinding>
<binding exactlyOnce="true" maxRetryCycles="1000" receiveRetryCount="1"
retryCycleDelay="00:10:00" timeToLive="7.00:00:00" useActiveDirectory="false">
</binding>
</netMsmqBinding>


This all works fine. When the DB is not available, the Rollback causes the queue entry to be put in the retry subqueue that I have configured to retry every 10 mins for 7 days. Everything about it works and has been in production for 6 months or so.



Now I am adding logging to the service. The QueueService is going to queue log entries into another queue we will call: LogQueue. The requirement is that whether the qTransaction is rolled back or not, a message should be sent to the LogQueue indicating the status of the request.



In the QueueService app.config I have added:



  <client>
<endpoint address="net.msmq://localhost/private/MyLogQueue"
binding="netMsmqBinding" bindingConfiguration="NetMsmqBinding_ILogContract"
contract="LogServiceReference.ILogContract" name="NetMsmqBinding_ILogContract">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
...
<binding name="NetMsmqBinding_ILogContract" timeToLive="7.00:00:00">
<security mode="None" />
</binding>


In the LogService app.config, I have:



    <service name="LogService.LogContract">
<endpoint address="net.msmq://localhost/private/MyLogQueue" binding="netMsmqBinding" contract="LogService.ILogContract">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
...
<netMsmqBinding>
<binding exactlyOnce="true" maxRetryCycles="1000" receiveRetryCount="1" retryCycleDelay="00:10:00" timeToLive="7.00:00:00" useActiveDirectory="false">
</binding>
</netMsmqBinding>
...


Then, at the end of the QueueItems method I do the following:



LogContractClient proxy = new LogContractClient();
proxy.LogTransaction(myLoggingInformation); // This queues myLoggingInformation to the LogQueue.


This all works fine too... until... a database is not available and the transaction is rolled back.



The Rollback will happen before the call to proxy.LogTransaction and I will get:



System.ServiceModel.CommunicationException: 'An error occurred while sending to the queue: The transaction specified cannot be enlisted. (-1072824232, 0xc00e0058).Ensure that MSMQ is installed and running. If you are sending to a local queue, ensure the queue exists with the required access mode and authorization.'


If I move the proxy.LogTransaction before the qTransaction.Rollback the log entry is never put in the LogQueue.



My working theory is that WCF considers the operations on the two queues: read from QueueService queue and write to LogQueue, as a single transaction. So, if I try to write to the LogQueue after the Rollback the transaction has already ended, but if I write to the LogQueue before calling Rollback the write to the queue is also rolled back.



Is there any way I can retain the ability to rollback the queueService transaction while not simultaneously rolling back the LogService transaction?










share|improve this question




















  • 1





    I would agree with your theory. Transactional consistency is being enforced against all the endpoints defined in the service. If you define the logging queue service endpoint in a separate <service /> within your config, do you see this behaviour?

    – tom redfern
    Nov 27 '18 at 15:20











  • Thanks for reading and understanding the problem! I like your thinking... but, In the LogService there is only one endpoint. In the QueueService I have two, but one is in the services section (to receive queued messages) and the other is in the client section (to send messages to the log).

    – shindigo
    Nov 27 '18 at 18:54






  • 1





    Ok now I understand. Please see answer...

    – tom redfern
    Nov 28 '18 at 8:14


















1















I have built a WCF service that processes an MSMQ, let's call the service QueueService. The Contract looks like this:



// Each call to the service will be dispatched separately, not grouped into sessions.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class QueueServiceContract : IQueueServiceContract
{
[OperationBehavior(TransactionScopeRequired = true)]
public void QueueItems(List<Item> items) // really should be called 'HandleQueueItems
{
// Early in the processing I do:
Transaction qTransaction = Transaction.Current;
...
// I then check if the destination database is available.
if(DB.IsAvailable)
... process the data
else
qTransaction.Rollback;
...
}


IQueueServiceContract looks like this:



// The contract will be session-less.  Each post to the queue from the client will create a single message on the queue.
[ServiceContract(SessionMode = SessionMode.NotAllowed, Namespace = "MyWebService")]
public interface IQueueServiceContract
{
[OperationContract(IsOneWay = true)]
void QueueItems(List<Item> items);
}


Relevant parts of the App.config for the queue service look like this.



<services>
<service name="QueueService.QueueServiceContract">
<endpoint address="net.msmq://localhost/private/MyQueueServiceQueue" binding="netMsmqBinding" contract="QueueService.IQueueServiceContract">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
...
<netMsmqBinding>
<binding exactlyOnce="true" maxRetryCycles="1000" receiveRetryCount="1"
retryCycleDelay="00:10:00" timeToLive="7.00:00:00" useActiveDirectory="false">
</binding>
</netMsmqBinding>


This all works fine. When the DB is not available, the Rollback causes the queue entry to be put in the retry subqueue that I have configured to retry every 10 mins for 7 days. Everything about it works and has been in production for 6 months or so.



Now I am adding logging to the service. The QueueService is going to queue log entries into another queue we will call: LogQueue. The requirement is that whether the qTransaction is rolled back or not, a message should be sent to the LogQueue indicating the status of the request.



In the QueueService app.config I have added:



  <client>
<endpoint address="net.msmq://localhost/private/MyLogQueue"
binding="netMsmqBinding" bindingConfiguration="NetMsmqBinding_ILogContract"
contract="LogServiceReference.ILogContract" name="NetMsmqBinding_ILogContract">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
...
<binding name="NetMsmqBinding_ILogContract" timeToLive="7.00:00:00">
<security mode="None" />
</binding>


In the LogService app.config, I have:



    <service name="LogService.LogContract">
<endpoint address="net.msmq://localhost/private/MyLogQueue" binding="netMsmqBinding" contract="LogService.ILogContract">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
...
<netMsmqBinding>
<binding exactlyOnce="true" maxRetryCycles="1000" receiveRetryCount="1" retryCycleDelay="00:10:00" timeToLive="7.00:00:00" useActiveDirectory="false">
</binding>
</netMsmqBinding>
...


Then, at the end of the QueueItems method I do the following:



LogContractClient proxy = new LogContractClient();
proxy.LogTransaction(myLoggingInformation); // This queues myLoggingInformation to the LogQueue.


This all works fine too... until... a database is not available and the transaction is rolled back.



The Rollback will happen before the call to proxy.LogTransaction and I will get:



System.ServiceModel.CommunicationException: 'An error occurred while sending to the queue: The transaction specified cannot be enlisted. (-1072824232, 0xc00e0058).Ensure that MSMQ is installed and running. If you are sending to a local queue, ensure the queue exists with the required access mode and authorization.'


If I move the proxy.LogTransaction before the qTransaction.Rollback the log entry is never put in the LogQueue.



My working theory is that WCF considers the operations on the two queues: read from QueueService queue and write to LogQueue, as a single transaction. So, if I try to write to the LogQueue after the Rollback the transaction has already ended, but if I write to the LogQueue before calling Rollback the write to the queue is also rolled back.



Is there any way I can retain the ability to rollback the queueService transaction while not simultaneously rolling back the LogService transaction?










share|improve this question




















  • 1





    I would agree with your theory. Transactional consistency is being enforced against all the endpoints defined in the service. If you define the logging queue service endpoint in a separate <service /> within your config, do you see this behaviour?

    – tom redfern
    Nov 27 '18 at 15:20











  • Thanks for reading and understanding the problem! I like your thinking... but, In the LogService there is only one endpoint. In the QueueService I have two, but one is in the services section (to receive queued messages) and the other is in the client section (to send messages to the log).

    – shindigo
    Nov 27 '18 at 18:54






  • 1





    Ok now I understand. Please see answer...

    – tom redfern
    Nov 28 '18 at 8:14














1












1








1








I have built a WCF service that processes an MSMQ, let's call the service QueueService. The Contract looks like this:



// Each call to the service will be dispatched separately, not grouped into sessions.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class QueueServiceContract : IQueueServiceContract
{
[OperationBehavior(TransactionScopeRequired = true)]
public void QueueItems(List<Item> items) // really should be called 'HandleQueueItems
{
// Early in the processing I do:
Transaction qTransaction = Transaction.Current;
...
// I then check if the destination database is available.
if(DB.IsAvailable)
... process the data
else
qTransaction.Rollback;
...
}


IQueueServiceContract looks like this:



// The contract will be session-less.  Each post to the queue from the client will create a single message on the queue.
[ServiceContract(SessionMode = SessionMode.NotAllowed, Namespace = "MyWebService")]
public interface IQueueServiceContract
{
[OperationContract(IsOneWay = true)]
void QueueItems(List<Item> items);
}


Relevant parts of the App.config for the queue service look like this.



<services>
<service name="QueueService.QueueServiceContract">
<endpoint address="net.msmq://localhost/private/MyQueueServiceQueue" binding="netMsmqBinding" contract="QueueService.IQueueServiceContract">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
...
<netMsmqBinding>
<binding exactlyOnce="true" maxRetryCycles="1000" receiveRetryCount="1"
retryCycleDelay="00:10:00" timeToLive="7.00:00:00" useActiveDirectory="false">
</binding>
</netMsmqBinding>


This all works fine. When the DB is not available, the Rollback causes the queue entry to be put in the retry subqueue that I have configured to retry every 10 mins for 7 days. Everything about it works and has been in production for 6 months or so.



Now I am adding logging to the service. The QueueService is going to queue log entries into another queue we will call: LogQueue. The requirement is that whether the qTransaction is rolled back or not, a message should be sent to the LogQueue indicating the status of the request.



In the QueueService app.config I have added:



  <client>
<endpoint address="net.msmq://localhost/private/MyLogQueue"
binding="netMsmqBinding" bindingConfiguration="NetMsmqBinding_ILogContract"
contract="LogServiceReference.ILogContract" name="NetMsmqBinding_ILogContract">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
...
<binding name="NetMsmqBinding_ILogContract" timeToLive="7.00:00:00">
<security mode="None" />
</binding>


In the LogService app.config, I have:



    <service name="LogService.LogContract">
<endpoint address="net.msmq://localhost/private/MyLogQueue" binding="netMsmqBinding" contract="LogService.ILogContract">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
...
<netMsmqBinding>
<binding exactlyOnce="true" maxRetryCycles="1000" receiveRetryCount="1" retryCycleDelay="00:10:00" timeToLive="7.00:00:00" useActiveDirectory="false">
</binding>
</netMsmqBinding>
...


Then, at the end of the QueueItems method I do the following:



LogContractClient proxy = new LogContractClient();
proxy.LogTransaction(myLoggingInformation); // This queues myLoggingInformation to the LogQueue.


This all works fine too... until... a database is not available and the transaction is rolled back.



The Rollback will happen before the call to proxy.LogTransaction and I will get:



System.ServiceModel.CommunicationException: 'An error occurred while sending to the queue: The transaction specified cannot be enlisted. (-1072824232, 0xc00e0058).Ensure that MSMQ is installed and running. If you are sending to a local queue, ensure the queue exists with the required access mode and authorization.'


If I move the proxy.LogTransaction before the qTransaction.Rollback the log entry is never put in the LogQueue.



My working theory is that WCF considers the operations on the two queues: read from QueueService queue and write to LogQueue, as a single transaction. So, if I try to write to the LogQueue after the Rollback the transaction has already ended, but if I write to the LogQueue before calling Rollback the write to the queue is also rolled back.



Is there any way I can retain the ability to rollback the queueService transaction while not simultaneously rolling back the LogService transaction?










share|improve this question
















I have built a WCF service that processes an MSMQ, let's call the service QueueService. The Contract looks like this:



// Each call to the service will be dispatched separately, not grouped into sessions.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class QueueServiceContract : IQueueServiceContract
{
[OperationBehavior(TransactionScopeRequired = true)]
public void QueueItems(List<Item> items) // really should be called 'HandleQueueItems
{
// Early in the processing I do:
Transaction qTransaction = Transaction.Current;
...
// I then check if the destination database is available.
if(DB.IsAvailable)
... process the data
else
qTransaction.Rollback;
...
}


IQueueServiceContract looks like this:



// The contract will be session-less.  Each post to the queue from the client will create a single message on the queue.
[ServiceContract(SessionMode = SessionMode.NotAllowed, Namespace = "MyWebService")]
public interface IQueueServiceContract
{
[OperationContract(IsOneWay = true)]
void QueueItems(List<Item> items);
}


Relevant parts of the App.config for the queue service look like this.



<services>
<service name="QueueService.QueueServiceContract">
<endpoint address="net.msmq://localhost/private/MyQueueServiceQueue" binding="netMsmqBinding" contract="QueueService.IQueueServiceContract">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
...
<netMsmqBinding>
<binding exactlyOnce="true" maxRetryCycles="1000" receiveRetryCount="1"
retryCycleDelay="00:10:00" timeToLive="7.00:00:00" useActiveDirectory="false">
</binding>
</netMsmqBinding>


This all works fine. When the DB is not available, the Rollback causes the queue entry to be put in the retry subqueue that I have configured to retry every 10 mins for 7 days. Everything about it works and has been in production for 6 months or so.



Now I am adding logging to the service. The QueueService is going to queue log entries into another queue we will call: LogQueue. The requirement is that whether the qTransaction is rolled back or not, a message should be sent to the LogQueue indicating the status of the request.



In the QueueService app.config I have added:



  <client>
<endpoint address="net.msmq://localhost/private/MyLogQueue"
binding="netMsmqBinding" bindingConfiguration="NetMsmqBinding_ILogContract"
contract="LogServiceReference.ILogContract" name="NetMsmqBinding_ILogContract">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
...
<binding name="NetMsmqBinding_ILogContract" timeToLive="7.00:00:00">
<security mode="None" />
</binding>


In the LogService app.config, I have:



    <service name="LogService.LogContract">
<endpoint address="net.msmq://localhost/private/MyLogQueue" binding="netMsmqBinding" contract="LogService.ILogContract">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
...
<netMsmqBinding>
<binding exactlyOnce="true" maxRetryCycles="1000" receiveRetryCount="1" retryCycleDelay="00:10:00" timeToLive="7.00:00:00" useActiveDirectory="false">
</binding>
</netMsmqBinding>
...


Then, at the end of the QueueItems method I do the following:



LogContractClient proxy = new LogContractClient();
proxy.LogTransaction(myLoggingInformation); // This queues myLoggingInformation to the LogQueue.


This all works fine too... until... a database is not available and the transaction is rolled back.



The Rollback will happen before the call to proxy.LogTransaction and I will get:



System.ServiceModel.CommunicationException: 'An error occurred while sending to the queue: The transaction specified cannot be enlisted. (-1072824232, 0xc00e0058).Ensure that MSMQ is installed and running. If you are sending to a local queue, ensure the queue exists with the required access mode and authorization.'


If I move the proxy.LogTransaction before the qTransaction.Rollback the log entry is never put in the LogQueue.



My working theory is that WCF considers the operations on the two queues: read from QueueService queue and write to LogQueue, as a single transaction. So, if I try to write to the LogQueue after the Rollback the transaction has already ended, but if I write to the LogQueue before calling Rollback the write to the queue is also rolled back.



Is there any way I can retain the ability to rollback the queueService transaction while not simultaneously rolling back the LogService transaction?







wcf transactions msmq






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 26 '18 at 19:48







shindigo

















asked Nov 26 '18 at 19:23









shindigoshindigo

9111224




9111224








  • 1





    I would agree with your theory. Transactional consistency is being enforced against all the endpoints defined in the service. If you define the logging queue service endpoint in a separate <service /> within your config, do you see this behaviour?

    – tom redfern
    Nov 27 '18 at 15:20











  • Thanks for reading and understanding the problem! I like your thinking... but, In the LogService there is only one endpoint. In the QueueService I have two, but one is in the services section (to receive queued messages) and the other is in the client section (to send messages to the log).

    – shindigo
    Nov 27 '18 at 18:54






  • 1





    Ok now I understand. Please see answer...

    – tom redfern
    Nov 28 '18 at 8:14














  • 1





    I would agree with your theory. Transactional consistency is being enforced against all the endpoints defined in the service. If you define the logging queue service endpoint in a separate <service /> within your config, do you see this behaviour?

    – tom redfern
    Nov 27 '18 at 15:20











  • Thanks for reading and understanding the problem! I like your thinking... but, In the LogService there is only one endpoint. In the QueueService I have two, but one is in the services section (to receive queued messages) and the other is in the client section (to send messages to the log).

    – shindigo
    Nov 27 '18 at 18:54






  • 1





    Ok now I understand. Please see answer...

    – tom redfern
    Nov 28 '18 at 8:14








1




1





I would agree with your theory. Transactional consistency is being enforced against all the endpoints defined in the service. If you define the logging queue service endpoint in a separate <service /> within your config, do you see this behaviour?

– tom redfern
Nov 27 '18 at 15:20





I would agree with your theory. Transactional consistency is being enforced against all the endpoints defined in the service. If you define the logging queue service endpoint in a separate <service /> within your config, do you see this behaviour?

– tom redfern
Nov 27 '18 at 15:20













Thanks for reading and understanding the problem! I like your thinking... but, In the LogService there is only one endpoint. In the QueueService I have two, but one is in the services section (to receive queued messages) and the other is in the client section (to send messages to the log).

– shindigo
Nov 27 '18 at 18:54





Thanks for reading and understanding the problem! I like your thinking... but, In the LogService there is only one endpoint. In the QueueService I have two, but one is in the services section (to receive queued messages) and the other is in the client section (to send messages to the log).

– shindigo
Nov 27 '18 at 18:54




1




1





Ok now I understand. Please see answer...

– tom redfern
Nov 28 '18 at 8:14





Ok now I understand. Please see answer...

– tom redfern
Nov 28 '18 at 8:14












1 Answer
1






active

oldest

votes


















1














I think you can fix this by wrapping the call to the log queue client in a transaction scope with TransactionScopeOption.Suppress set. This will force the action to happen outside of the ambient transaction.



Something like:



using (var scope = new TransactionScope (TransactionScopeOption.Suppress))
{
// Call to enqueue log message
}


Your theory makes perfect sense. Because you're using transactional queues WCF is ensuring transactional consistency by enlisting everything inside the message handler in a DTC transaction. That obviously includes the enqueue of the logging message, and is expected, if unwanted, behaviour.






share|improve this answer


























  • Wow - just wow! That did it! Thanks so much!

    – shindigo
    Nov 28 '18 at 16:13











  • @shindigo glad to have helped!

    – tom redfern
    Nov 28 '18 at 17:18












Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53487724%2fwcf-msmq-and-independent-transactions-on-2-queues%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














I think you can fix this by wrapping the call to the log queue client in a transaction scope with TransactionScopeOption.Suppress set. This will force the action to happen outside of the ambient transaction.



Something like:



using (var scope = new TransactionScope (TransactionScopeOption.Suppress))
{
// Call to enqueue log message
}


Your theory makes perfect sense. Because you're using transactional queues WCF is ensuring transactional consistency by enlisting everything inside the message handler in a DTC transaction. That obviously includes the enqueue of the logging message, and is expected, if unwanted, behaviour.






share|improve this answer


























  • Wow - just wow! That did it! Thanks so much!

    – shindigo
    Nov 28 '18 at 16:13











  • @shindigo glad to have helped!

    – tom redfern
    Nov 28 '18 at 17:18
















1














I think you can fix this by wrapping the call to the log queue client in a transaction scope with TransactionScopeOption.Suppress set. This will force the action to happen outside of the ambient transaction.



Something like:



using (var scope = new TransactionScope (TransactionScopeOption.Suppress))
{
// Call to enqueue log message
}


Your theory makes perfect sense. Because you're using transactional queues WCF is ensuring transactional consistency by enlisting everything inside the message handler in a DTC transaction. That obviously includes the enqueue of the logging message, and is expected, if unwanted, behaviour.






share|improve this answer


























  • Wow - just wow! That did it! Thanks so much!

    – shindigo
    Nov 28 '18 at 16:13











  • @shindigo glad to have helped!

    – tom redfern
    Nov 28 '18 at 17:18














1












1








1







I think you can fix this by wrapping the call to the log queue client in a transaction scope with TransactionScopeOption.Suppress set. This will force the action to happen outside of the ambient transaction.



Something like:



using (var scope = new TransactionScope (TransactionScopeOption.Suppress))
{
// Call to enqueue log message
}


Your theory makes perfect sense. Because you're using transactional queues WCF is ensuring transactional consistency by enlisting everything inside the message handler in a DTC transaction. That obviously includes the enqueue of the logging message, and is expected, if unwanted, behaviour.






share|improve this answer















I think you can fix this by wrapping the call to the log queue client in a transaction scope with TransactionScopeOption.Suppress set. This will force the action to happen outside of the ambient transaction.



Something like:



using (var scope = new TransactionScope (TransactionScopeOption.Suppress))
{
// Call to enqueue log message
}


Your theory makes perfect sense. Because you're using transactional queues WCF is ensuring transactional consistency by enlisting everything inside the message handler in a DTC transaction. That obviously includes the enqueue of the logging message, and is expected, if unwanted, behaviour.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 28 '18 at 8:13

























answered Nov 28 '18 at 7:40









tom redferntom redfern

24k1064102




24k1064102













  • Wow - just wow! That did it! Thanks so much!

    – shindigo
    Nov 28 '18 at 16:13











  • @shindigo glad to have helped!

    – tom redfern
    Nov 28 '18 at 17:18



















  • Wow - just wow! That did it! Thanks so much!

    – shindigo
    Nov 28 '18 at 16:13











  • @shindigo glad to have helped!

    – tom redfern
    Nov 28 '18 at 17:18

















Wow - just wow! That did it! Thanks so much!

– shindigo
Nov 28 '18 at 16:13





Wow - just wow! That did it! Thanks so much!

– shindigo
Nov 28 '18 at 16:13













@shindigo glad to have helped!

– tom redfern
Nov 28 '18 at 17:18





@shindigo glad to have helped!

– tom redfern
Nov 28 '18 at 17:18




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53487724%2fwcf-msmq-and-independent-transactions-on-2-queues%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Wiesbaden

Marschland

Dieringhausen