Under what circumstances would I see the above message? I have a single call to SQL Server which is wrapped in a call to TransactionScope. In our development and QA environments MSDTC is turned off and the call succeeds fine. However, in our production environment with MSDTC turned on we are failing with this call. Is there something that would cause this when I am sure we are not looking at a distributed transaction call at all?
Ok, so the problem was that we had a CreateTransaction call around the call AND a TransactionScope. So we DID have 2 transactions. I didn't think that this would cause this type of problem until I realized that when there was an error we would end up with two ROLLBACK calls. The second one would trigger the above error message and effectively hide the first. We found this by running SQLProfiler looking for "User Error Messages"
Related
Im trying to get SQL Notifications to work with BizTalk, but im struggling a one point.
The Binding of the Receivelocation is the following:
The SQL Server is supporting Notifications, and the connection string is correct.
When i start the Receivelocation it is working exactly one time in a correct way, but when i disable it and start it again, i get the following error in the eventlog.
The Messaging Engine failed to add a receive location
"RL.MDM.SQL" with URL
"mssql://.//Database?InboundId=GetNewMDMChanges" to the adapter
"WCF-SQL". Reason:
"Microsoft.ServiceModel.Channels.Common.TargetSystemException: The
notification callback returned an error. Info=Invalid.
Source=Statement. Type=Subscribe.
I cant start the Receivelocation again till i Execute the following command on the Database to enable the Broker.
alter database MDMDEV set enable_broker with rollback immediate;
The strange thing here is when i check if the broker is still enabled before i execute the command above, i see that the broker is indeed still enabled.
So the command to enable the broker fixes my problem for exactly one other notification and than i have to do this again.
Has anybody ever had this problem or can tell me what im doing wrong?
Thanks in advance.
Regarding the Notifications feature in general, my recommendation is to not use it.
With both SQL Server and Oracle, the Notifications feature is quite fragile and will stop receiving event with no warning or error. When this happens, the only way to recover is Disable/Enable the Receive Location.
Basically, I have found it not reliable enough to use in production apps.
If you or your organization own the database, Polling [+ Triggers if needed] are 100% reliable.
This article describes some different Polling scenarios: BizTalk Server: SQL Patterns for Polling and Batch Retrieve
Dears,
I have scenarios where I have to perform updates on the intrinsic database of LightSwitch and call some SQL stored procedures in the save pipeline all in ONE TRANSACTION, such that if an error happened in the LS save pipeline then my stored procedure calls are rolled back.
The recommended way of doing this is to set up an ambient transaction in the SaveChanges_Executing event, and to dispose of it in the SaveChanges_Executed and SaveChanges_ExecuteFailed events. As described in this articles http://www.codemag.com/Article/1103071
But this has two fatal problems:
It does not work when I publish the app on Azure since distributed transactions are not supported there.
Also it throws an error when I try to save changes to ApplicationData sources using the ServerApplicationContext. The error is this: The underlying provider failed on EnlistTransaction
Has anyone found a cleaner way to handle transactions in LightSwitch that works both on Azure and through ServerApplicationContext??
Thanks a lot
Currently, distributed transactions using MSDTC do not work against SQL Azure. They will work just fine against SQL Server in a VM running in Azure, however. MSDTC is tied to running on a domain controller, generally, and that doesn't make sense in the public cloud context. An alternative DTC is likely needed, but this is not something that has been publicly announced as of today.
I don't think Lightswitch is the main issue here (though perhaps it has some additional issue beyond what I have described).
I hope that at least explains why it doesn't work today - I wish I had a better answer for you, but right now it is not possible. The "workarounds" being used are to build applications that can be resilient to the commits happening on each side (or not) and recovering from the failed cases.
Reason for System.Transactions.TransactionInDoubtException mentions three reasons for transactions being promoted to MSDTC. The first two are fairly well known, however the third reason is the following:
3.If you have "try/catch{retry if timeout/deadlock}" logic that is running within your code, then this can cause issues when the transaction is within a System.Transactions.TransactionScope, because of the way that SQL Server automatically rolls back transaction when a timeout or deadlock occurs.
I am seeing this behavior in one of my server apps when it is under severe load (SQL 2012). I've tried Googling extensively, but I'm not finding any more info. Does anyone have any references to additional information on this topic?
thanks,
Larry
I guess we're really running one transaction over one connection with a ref count of two. Which I agree is bogus and should be re-coded.
This is not a problem by itself.
However, there times when the inner transaction rolls back and retries
The problem is that a rollback rolls back everything. You can't retry the "inner" work in isolation. (Yes, this would be super useful but SQL Server does not support it.)
This looks to fire up a second connection for the inner transaction. Which would cause MSDTC to be invoked to try to coordinate.
This is moot because at this point the "outer" work has been destroyed.
There is no great solution for this problem. The best strategy is likely to have only one transaction and retry outer and inner work as one unit. Retries always must retry the entire transaction. You can use transaction "ref counting" if you want but you can't use it to rollback.
A particular nasty feature of SQL Server is that it is unpredictable whether any particular error causes the transaction to roll back. Therefore it is the cleanest way to never handle errors with SQL Server and always declare the transaction to be lost. (There is no technical reason SQL Server has to do this. It's just a stupid design choice.)
We're running NServiceBus for a web application to handle situations where the user do "batch like" actions. Like fire a command that affects 1000 entities..
It works well, but during moderate load we get some deadlocks, this isn't a problem, just retry the message.. right? :)
The problem occurs when the next message arrives and tries to open a connection. The connection is then "corrupt".
We get the following error:
System.Data.SqlClient.SqlException (0x80131904): New request is not allowed to start because it should come with valid transaction descriptor
I've searched the web and I think our problem is a reported NH "bug":
A workaround should be to disable connection pooling. But I don't like that, since performce will degrade..
We're running NServiceBus 2.6, NHibernate 3.3.
Does anyone have any experience with this? Can a upgrade of NServiceBus help?
I’ve seen this in the past, if your design warrants, try breaking the transaction into two, if you flow the message transaction all the way to your database operations, any failures will have a cascading effect and it will impact (ideally it shouldn’t) any subsequent messages as well.
Instead of updating the 1000 entities in the command could you publishing an event to say that the command has been completed and then have several subscribers acting on this event to update effect entities. It sounds to me that a command that updates a 1000 entities should be split into a number of smaller commands. Take a look a the sagas to see how you can handle long running business process. For example, you might have something like, process started, step 1 completed, step 2 completed , process completed etc...
Quick overview of our topology:
Web sites sending commands to an nServiceBus server, which accepts the commands and then publishes the correct pub/sub events. This service also has message handlers that can do some process against the DB in response to the command, for instance:
1 user registers on web site
2 web site sends nServicebus command to nServicebus service on another server.
3 nServicebus server has a handler for that specific type of command, which logs something to the database and sends a welcome email
Since instituting this architecture we started to get deadlocks on the DB. I have traced it down to MSDTC on the database server. If I turn that service OFF on the database server nServicebus starts throwing up errors, which to me shows that nServiceBus has been enlisting the DB update in the transaction.
I don't wish this to happen, I want to handle the DB failing myself, I only want the transaction to ensure the message is delivered to my nServicebus proxy service. I don't want a transaction from the web all the way through 2 servers to the DB and back.
Any suggestions?
EDIT: this post provides some clues, however I'm not entirely sure it's the proper way to proceed.. NServiceBus - Problem with using TransactionScopeOption.Suppress in message handler
EDIT2: The reason that we want the DB work outside the scope of the transaction is that the intent is to 'asynchronously' process these commands on another server so as not to slow down the web site and/or cause users to wait for these long running aggregation commands. If the DB is within the scope of the transaction, is that blocking execution on the website at the point where the original command is fired to the distributor? Is there a better nServicebus architecture for this scenario? We want the command to fire quickly and return control to the web site so the user can quickly proceed and not have to wait for our longish running DB command, which is updating aggregate counts and sending emails etc.
I wouldn't recommend having the DB work outside the context of the NServiceBus transaction. Instead, try reducing the isolation level of the transactions. This can be done by calling:
.IsolationLevel(System.Transactions.IsolationLevel.ReadCommited)
in the fluent configuration. You'll have to put this after .MsmqTransport() in v2.6. In v3.0 you can put this call almost anywhere.
RESPONSE TO EDIT2:
Just using NServiceBus will achieve your objective of not slowing down the website, regardless of the level of the transactions run on the other server. The use of transactions is to provide a guarantee that messages won't be lost in case of failure and also that you won't have to write your own deduplication logic.