We are using ReliableSqlConnection from Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling to support transient fault handling for Azure database, we are on .NET 4.6.1. The thing is randomly we got exception:
"Internal .Net Framework Data Provider error 6"
when trying to open connection with this class. ReliableSqlConnection does not support async await, but built-in transient fault handling with ConnectRetryInterval and ConnectRetryCount on ADO.NET 4.6.1 only support at connection level, not command level.
Is there any alternative for ReliableSqlConnection in order to supportat command level with async await and avoid the above exception.
We use Elastic Pool on Azure SQL with tier standard.
Related
In an Open Shift cluster environment, I am having processing time periods where we are getting various timeout expired exceptions from Entity Framework Core v2.1. I am in the process of upgrading my app to .NET Core 6.0. The exceptions occur on queries to SQL Server and appear to not be related to memory or processing resources. Seems more likely that it is load on the network where we may be having network connection timeouts to the SQL Server.
Some of the exceptions also include the following case:
System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
System.ComponentModel.Win32Exception (258): Unknown error 258
Looking at next steps, I have read some about Entity Framework interceptors. Would using Entity Framework interceptors be a good use of this feature for debugging timeout expired issues?
Could I use an interceptor to catch the timeout exception details, better inside the Entity Framework DLL?
Looking for best practices for pin pointing causes of DB connection timeouts occurring under peak loads, where simple DB queries are timing out.
I am using Microsoft.ServiceBus.dll (version 2.1) in order to work on Service Bus for Windows Server 1.1.
We also want this library to be able to talk to Azure Service bus. It only works on the computer in one domain (no port restriction). However on a computer in a more restricted domain (some ports are blocked), I got following error. If I switch Microsoft.ServiceBus.dll 3.0, then the same code works in the restricted domain. Why does Microsoft.ServiceBus.dll 3.0 work and Microsoft.ServiceBus.dll 2.1 does not work in the same lab (domain)?
Could not connect to net.tcp://xxx.servicebus.windows.net:9354/. The connection attempt lasted for a time span of 00:00:20.9992011.
TCP error code 10060: A connection attempt failed because the connected party did not properly respond after a period of time, or established
connection failed because connected host has failed to respond 40.86.102.100:9354.
at Microsoft.ServiceBus.Common.AsyncResult.End[TAsyncResult](IAsyncResult result)
at Microsoft.ServiceBus.Messaging.IteratorAsyncResult1.RunSynchronously()
at Microsoft.ServiceBus.Messaging.MessageSender.OnSend(TrackingContext trackingContext, IEnumerable1 messages, TimeSpan timeout)
at Microsoft.ServiceBus.Messaging.MessageSender.Send(TrackingContext trackingContext, IEnumerable`1 messages, TimeSpan timeout)
at Microsoft.ServiceBus.Messaging.MessageSender.Send(BrokeredMessage message)
at Microsoft.ServiceBus.Messaging.QueueClient.Send(BrokeredMessage message)
When I used Microsoft.ServiceBus.dll 3.0 to talk to SB for Windows Server 1.1, I got the following error:
"The remote server returned an error: (400) Bad Request. The api-version in the query string is not supported. Either remove it from the Uri or use one of '2012-03,2012-08,2013-04,2013-07'."
Based on this link Service Bus 1.1 creating Queue with WindowsAzure.ServiceBus dll, I have to use Microsoft.ServiceBus.dll 2.1.
I would like to use a Microsoft.ServiceBus.dll version that can talk to both Azure Service bus and SB for Windows Server 1.1. It seems 2.1 is the only choice, but it give me
trouble in that restricted domain.
Why does Microsoft.ServiceBus.dll 3.0 work and Microsoft.ServiceBus.dll 3.1
Based on your description, It seems you write wrong version of Microsoft.serverBus.dll 3.1. Can we understand as version 2.1?
From the Microsoft Azure Service Bus release note, we could find below information:
• General: Compiled against .Net 4.5 - .Net 4.0 projects will need to recompile against .Net 4.5 as well.
• General: Removal of old Begin/End style async API for all Messaging and EventHub classes. Please use Task base async API instead.
The version above 3.0 will compiled against .Net4.5. So if your application use .Net 4.5. It is better to choose the version of Microsoft.ServiceBus.dll higher than 3.0.
Azure documentation lacks and articles are often obsolete.
I've read that "Transient Fault Handling" (TFH) for Azure services (ServiceBus, FileStorage...) is now fully managed. It seems now there is nothing to implement on the client side. In the past, we could use Enterprise Library to manage such purposes but it is retired. For accessing SQL Database, a policy is implemented for Entity Framework (https://msdn.microsoft.com/en-us/data/dn456835.aspx).
Here are my questions :
Is it necessary to use Azure SDK on ServiceBus and FileStorage to benefit from policies that are now implemented on Azure ?
How is it possible to manage TFH when accessing data with something that is not EF ?
We need to ensure that our components (that use WebClient, raw ADO.NET...) will run correctly in a maintanable way.
I've read that "Transient Fault Handling" (TFH) for Azure services
(ServiceBus, FileStorage...) is now fully managed. It seems now there
is nothing to implement on the client side.
This is not correct. The service by itself will not handle transient errors. It is the responsibility of the client to handle transient errors. If you look at Storage Client Library (>= version 2.0), you will find retry policies there using which you can instruct your client code to handle transient errors.
Now coming to your questions:
Is it necessary to use Azure SDK on ServiceBus and FileStorage to
benefit from policies that are now implemented on Azure ?
It is certainly not necessary to use SDKs to handle transient errors but they make your job easier. SDKs come up with a variety of ways to handle transient errors (plus you could extend the functionality available in the SDK to come up with your own transient handling strategy). To elaborate, let's consider Storage Client library which is a wrapper over Azure Storage REST API. Now this library has defined which errors should be considered transient (HTTP Status Code 500+) and which errors should not be considered transient (HTTP Status Code 400 - 499). Furthermore it comes with different kinds of retry logic - Exponential (default), Linear, or None. As a developer, you can decide what retry logic should be used in case of a transient error and bake that into your code. If you were not using these SDKs, everything needs to be done by you starting from which errors should be considered transient and how the retry should be implemented. SDKs just make your job easier.
How is it possible to manage TFH when accessing data with something
that is not EF ?
If you're using ADO.Net and you get an exception, what you can do is take a look at the ErrorCode returned by the service and determine if the error is transient or not. For a list of SQL Error Codes, please see this link: https://azure.microsoft.com/en-in/documentation/articles/sql-database-develop-error-messages/. I would also highly recommend reading this article as well as to how you would go about implementing your own TFH: https://azure.microsoft.com/en-in/documentation/articles/sql-database-connectivity-issues/.
When we first migrated to Azure, transient fault handling via the Enterprise Application Block 5.0 was the best game in town. We use it to automatically perform retries when getting an Azure SQL Connection, accessing ASP.NET Session objects and accessing ASP.NET Application objects. To do so, we make use of the following classes respectively:
ReliableSqlConnection from the Application Block
Our own ReliableApplication class that extends Microsoft.ApplicationServer.Caching.DataCache by applying the Application Block cache RetryPolicy when accessing Application objects
Our own ReliableSession class that extends HttpContext.Current.Session by applying the Application Block cache RetryPolicy when accessing Session objects.
Now according to Microsoft's Transient Fault Handling Patterns and Practices as of March 2014:
Recent versions of SDKs for both Azure Storage and Azure Service Bus natively support retries. It is recommended to use these instead of the Transient Fault Handling Application Block
What Azure SDK classes should we use to replace our dependencies on deprecated Enterprise Application Block Transient Fault Handling?
Please follow the following blog posts to implement retry logic(These are ADO.NET samples but you can replicate the logic in the language of your choice)
https://msdn.microsoft.com/library/azure/ee336243.aspx
https://msdn.microsoft.com/en-us/library/azure/dn961167.aspx
The first one is implementing retry logic using the Enterprise Library and the second one shows you how to implement retry logic using custom code.
To answer your question :
What Azure SDK classes should we use to replace our dependencies on deprecated Enterprise Application Block Transient Fault Handling?
You will have to use retry logic to improve connection resiliency. Unfortunately there is no Azure SDK that you can use currently to implement retry logic to connect to Azure SQL DB.
Let me know if this makes sense.
Best,
Meet Bhagdev
Program Manager, Microsoft
This site has examples for the native client support for each service
https://github.com/mspnp/azure-guidance/blob/master/Retry-Service-Specific.md
First a little intro to our setup:
WCF based app with EF 4 context injected using Unity (no singleton)
Oracle running on a seperate physical machine
NServiceBus handling messages that access Oracle through the same context as above
The problem we are experiencing, only on our UAT environment, is that we cannot send multiple messages without receiving distributed transaction locks on DTC. The DTC trace tells us this:
1. TRANSACTION_COMMITTED
2. RM_ISSUED_COMMIT
3. RM_ISSUED_COMMIT
4. RM_ACKNOWLEDGED_COMMIT
5. RM_COMMIT_DELIVERY_FAILED_DUE_TO_CONNECTION_DOWN
Any bright ideas?
It seems the problem lies within our client app WCF configuration.
Deep down in our framework we are setting TransactionFlow = true which tries to setup a transaction scope starting from the client. If we run our request and fire of a NServiceBus message we loose the link with our client and cannot commit the transaction.
So TransactionFlow = false in app.config saved us.