Azure - WebJob timeout when calling stored procedure - sql-server

I have a webjob that calls a long running stored procedure that keeps timing out. Can anyone help please?
The web job is called using the following code:
static void Main()
{
ApplicationDbContext context = new ApplicationDbContext();
context.Database.CommandTimeout = 6000;
context.PopulateJobTypeDescendants();
}
The method on the context (ApplicationDbContext) is shown below:
public void PopulateJobTypeDescendants()
{
Database.ExecuteSqlCommand("PopulateJobTypeDescendants");
}
The following exception is raised when the web job is run. We have read that it could be related to the plan/DTUs on the server so we went from S1 -> S3, this still didn't solve the issue and the process bombs out after 45 seconds. The strange thing is that if I connect to azure sql db from SSMS and call the stored procedure it works fine.
[07/11/2016 22:25:02 > e2cf50: ERR ] Unhandled Exception:
System.Data.SqlClient.SqlException: Timeout expired. The timeout
period elapsed prior to completion of the operation or the server is
not responding. This failure occurred while attempting to connect to
the routing destination. The duration spent while attempting to
connect to the original server was - [Pre-Login] initialization=14;
handshake=26; [Login] initialization=0; authentication=0; [Post-Login]
complete=1; ---> System.ComponentModel.Win32Exception: The wait
operation timed out
The connection string is shown below:
<add name="TempsContext" connectionString="Server=tcp:[XXX],1433;Database=temps_testing;User ID=[XXX];Password=[XXX];Trusted_Connection=False;Encrypt=True;Connection Timeout=600;" providerName="System.Data.SqlClient" />

It is possible that this is caused by some inconsistencies in how EF propagates the value of CommandTimeout to the commands its creates, e.g. to do database initialization or to obtain versioning information from the server.
It should be possible to use command interception as a workaround, e.g.:
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Infrastructure.Interception;
namespace CommandTimeOutBug
{
class Program
{
static void Main(string[] args)
{
DbInterception.Add(new MyInterceptor());
using (var context = new ApplicationDbContext())
{
context.Database.CommandTimeout = 6000;
context.PopulateJobTypeDescendants();
}
}
}
public class ApplicationDbContext : DbContext
{
public void PopulateJobTypeDescendants()
{
Database.ExecuteSqlCommand("PopulateJobTypeDescendants");
}
}
public class MyInterceptor: DbCommandInterceptor
{
public override void NonQueryExecuting(DbCommand command,
DbCommandInterceptionContext<int> interceptionContext)
{
command.CommandTimeout = 6000;
base.NonQueryExecuting(command, interceptionContext);
}
public override void ReaderExecuting(DbCommand command,
DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
command.CommandTimeout = 6000;
base.ReaderExecuting(command, interceptionContext);
}
public override void ScalarExecuting(DbCommand command,
DbCommandInterceptionContext<object> interceptionContext)
{
command.CommandTimeout = 6000;
base.ScalarExecuting(command, interceptionContext);
}
}
}
I have created a bug at https://github.com/aspnet/EntityFramework6/issues/24 to track this.

Indeed it looks like a performance issue. Could you please reply me offline at mihaelab at micrososft dot com with server, database names details and full call stack of the exception?
Thanks,
Mihaela

Related

EF Core set XACT_ABORT for all database connections

I am using EF Core 3.1 to connect to SQL Server. I would like to SET XACT_ABORT ON for SQL Server on for all the connections I make in my application.
Is there a hook on start up or context creation that I can run this? Because I am working with AWS RDS, I do not have the ability to turn it on server wide.
Any help would be appreciated.
Open the SqlConnection and set XACT_ABORT ON before passing the open SqlConnection to your DbContext constructor. The pattern for BYO-connection in EF core is
SqlConnection con;
public Db(SqlConnection con)
{
this.con = con;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseLoggerFactory(loggerFactory)
.UseSqlServer(con, o => o.UseRelationalNulls());
base.OnConfiguring(optionsBuilder);
}
public override void Dispose()
{
con.Close();
base.Dispose();
}
or if you're using DI, introduce a IDbConnectionFactory or somesuch and write
public Db(IDbConnectionfactory cf)
{
this.con = cf.GetConnection();
}
Passing an open connection to the DbContext constructor will prevent the DbContext from opening and closing the connection for each command. This might slightly increase the size of your connection pool, but it shouldn't be a big deal.

Spring boot Oracle JPA set QueryTimeout

I'm using Spring Boot with Ojdbc8 18.3.0.0.0
With Hikari Datasource and JPA, all query work fine.
But now I need to set Query timeout for all database query
I was try many way:
javax.persistence.query.timeout=1000
spring.transaction.default-timeout=1
spring.jdbc.template.query-timeout=1
spring.jpa.properties.hibernate.c3p0.timeout=1
spring.jpa.properties.javax.persistence.query.timeout=1
Config Class:
#Configuration
public class JPAQueryTimeout {
#Value("${spring.jpa.properties.javax.persistence.query.timeout}")
private int queryTimeout;
#Bean
public PlatformTransactionManager transactionManager() throws Exception {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setDefaultTimeout(queryTimeout); //Put 1 seconds timeout
return txManager;
}
}
Query:
List<Integer> llll = manager.createNativeQuery("select test_sleep(5) from dual")
.setHint("javax.persistence.query.timeout", 1).getResultList();
The database task take 5 second before return value, but in all of case, no error occor.
Could anyone tell me how to set query timeout?
You can try using the simplest solution, that is using the timeout value within #Transactional;
#Transactional(timeout = 1) // in seconds (so that is 1 second timeout)
public Foo runQuery(String id) {
String result = repo.findById(id);
// other logic
}
Be aware that the method annotated with #Transactional must be public for it to work properly

Can't connect to SQL 2008 database using .NET Core 2.0

UPDATE
I could never make this work with a "Windows Authentication" (domain) user. But with a "SQL Server Authentication" user everything is working like it's supposed to.
ORIGINAL QUESTION
My connectionString: Server=ip;Database=dbname;User Id=xxx\user;Password=pass;
The connection string is located in appsettings.json like this:
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Warning"
}
},
"ConnectionStrings": {
"ConnectionString": "Server=ip;Database=dbname;User Id=xxx\user;Password=pass;"
}
}
Then i pass it to a static class from the "Startup.cs" file, like this:
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
Orm.DatabaseConnection.ConnectionString = Configuration["ConnectionStrings:ConnectionString"];
}
This is where I initiate the connection:
using System.Data.SqlClient;
namespace MyProject.Orm
{
public static class DatabaseConnection
{
public static string ConnectionString { get; set; }
public static SqlConnection ConnectionFactory()
{
return new SqlConnection(ConnectionString);
}
}
}
And this is my controller:
public string Get()
{
using (var databaseConnection = Orm.DatabaseConnection.ConnectionFactory())
{
var sections = databaseConnection.Query("SELECT * FROM myTable").ToList();
return sections.ToString();
}
}
Where this line:
var databaseConnection = Orm.DatabaseConnection.ConnectionFactory();
returns:
ServerVersion: "'databaseConnection.ServerVersion' threw an exception of type 'System.InvalidOperationException'"
Message: "Invalid operation. The connection is closed."
Source: "System.Data.SqlClient"
StackTrace: "at
System.Data.SqlClient.SqlConnection.GetOpenTdsConnection()\n
at
System.Data.SqlClient.SqlConnection.get_ServerVersion()"
And i get this error on new SqlConnection: "error CS0119: 'SqlConnection' is a type, which is not valid in the given context".
But the program execution doesn't stop because of these errors.
The application then hangs on the following line:
var sections = databaseConnection.Query("SELECT * FROM myTable").ToList();
I'm using Dapper as my ORM (not EntityFramework). In "myTable" sql table are only 17 rows and 5 columns so it should load fast.
I tried all kinds of different connectionStrings but it always fails. If i try the same with .NET Framework 4.5, everything works fine. The problem is .NET Core 2.0.
Any idea about fixing it is welcome. Because i spent too many hours on this already.
Try to add databaseConnection.Open().
public string Get()
{
using (var databaseConnection = new SqlConnection(#"Server=ip;Database=dbname;User Id=xxx\user;Password=pass;Pooling=false;"))
{
databaseConnection.Open();
var sections = databaseConnection.Query("SELECT * FROM myTable").ToList();
return sections.ToString();
}
}
To avoid problems with connection pool that described in comments you add Pooling=false; to connection string:
Server=ip;Database=dbname;User Id=xxx\user;Password=pass;Pooling=false;
Edit:
I hardcoded connection string and removed factory to make example smaller
Try creating a self-contained deployment, this should eliminate and strange dependency stuff. If it works then at least you know that it's due to some assembly binding type stuff.
The exception "error CS0119: 'SqlConnection' is a type, which is not valid in the given context" smells like it is.

Connecting to Azure Service Bus from SSIS

I need to put a message into an Azure ServiceBus queue from an SSIS package running under SQL Server 2014. As suggested in this post: connecting to azure service bus queue from ssis,
I wrote a Script Task that references the "Azure SDK 2.9". This approach has worked for me with Azure Storage Accounts to work with blobs (referencing the Microsoft.WindowsAzure.Storage assembly), but it is NOT working for the Azure Storage Bus (referencing the Microsoft.ServiceBus assembly). Any calls I make into that assembly trigger a Run-time exception: "exception has been thrown by the target of an invocation: at System.RuntimeMethodHandle.InvokeMethod(...)" When I comment out all calls to the Microsoft.ServiceBus assembly it runs fine, so it is obviously something about the assembly reference (version 2.4). I tried updating to the latest version with NuGet (version 3.0) and that made no difference.
So my question is: has anybody been able to place a message in an Azure Service Bus queue from SSIS, and if so, how did you do it?
Since somebody will ask for my Script Task code, I'm posting it:
#region Namespaces
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
#endregion
#region CustomNamespaces
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
#endregion
namespace ST_dba6519c1eda4e0c968485a6eb7a6c29
{
[Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
public void Main()
{
try
{
// Create the message for the Queue
string ClientShortName = Dts.Variables["$Package::ClientShortName"].Value.ToString();
bool bExtendedForecast = (bool)Dts.Variables["$Package::ExtendedForecast"].Value;
var msg = new BrokeredMessage(ClientShortName + ": ExtendedForecast=" + bExtendedForecast.ToString()); // this statement throws the exception
// get Service Bus Connection Information from the Package Parameters
string SBAccessKey = Dts.Variables["$Package::ServiceBusAccessKey"].Value.ToString();
string SBNamespace = Dts.Variables["$Package::ServiceBusNamespace"].Value.ToString();
string SBQueue = Dts.Variables["$Package::ServiceBusQueueName"].Value.ToString();
String connStr = "Endpoint=sb://" + SBNamespace +
".servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=" + SBAccessKey;
// First Method tried
Uri SBUri = ServiceBusEnvironment.CreateServiceUri(String.Empty, SBNamespace, String.Empty); // this statement throws the exception
TokenProvider SBToken = TokenProvider.CreateSharedAccessSignatureTokenProvider("RootManageSharedAccessKey", SBAccessKey);
NamespaceManager nsMgr = new NamespaceManager(SBUri, SBToken);
MessagingFactory msgFactory = MessagingFactory.Create(nsMgr.Address, nsMgr.Settings.TokenProvider);
QueueClient queueClient2 = msgFactory.CreateQueueClient(SBQueue);
queueClient2.Send(msg);
// Second Method tried
MessagingFactory factory = MessagingFactory.CreateFromConnectionString(connStr); // this statement throws the exception
MessageSender queueSender = factory.CreateMessageSender(SBQueue);
queueSender.Send(msg);
// Third Method tried
QueueClient queueClient = QueueClient.CreateFromConnectionString(connStr, SBQueue); // this statement throws the exception
queueClient.Send(msg);
Dts.TaskResult = (int)ScriptResults.Success;
}
catch
{
Dts.TaskResult = (int)ScriptResults.Failure;
}
}
#region ScriptResults declaration
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
}
}
So, of course 10 minutes after I post the question, I hit upon the answer. I had to run GACUTIL -i Microsoft.ServiceBus. Once that was done, I chose to use the Third Method in the code (the simplest) to Send the message, and it worked fine.

Duplex WCF Client does not work with WinForms or WPF, but works fine with Console

I have a very peculiar case here.
I have implemented a wsDualHttpBinding WCF duplex server that is being consumed by a Windows Service.
The contract and implementation on the server side is defined as follows:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class FixServerContract : IFixContract
{
public FixServerContract()
{
}
public void Requestlogin(string message)
{
try
{
IServerCallback callback = OperationContext.Current.GetCallbackChannel<IServerCallback>();
callback.BroadcastToClient("Greetings from server");
}
catch (Exception ex)
{
}
}
[ServiceContract(CallbackContract=typeof(IServerCallback))]
public interface IFixContract
{
[OperationContract]
void Requestlogin(string message);
}
public interface IServerCallback
{
[OperationContract(IsOneWay = true)]
void BroadcastToClient(string eventData);
}
On the client end, I also have a single callback class, with the attached callback interface accessed by adding a Service Reference to the Client project as follows:
class MyCallbackClass : IFixContractCallback
{
public void RegisterClient()
{
InstanceContext context = new InstanceContext(this);
FixContractClient proxy = new FixContractClient(context);
proxy.Requestlogin("hello");
}
public void BroadcastToClient(string eventData)
{
}
}
When proxy.RequestLogin("hello"); is called by the client, the server should respond by signaling BroadcastToClient(string eventData)
But, here is where the peculiar behavior begins!
When my client calls RegisterClient directly from Main, outside of a Winform or WPF environment, everything works as it should be. That is, RequestLogin is successfully called to the server, and the server successfully responds by signalling BroadcastToClient on the client end.
This is shown here:
[STAThread]
private static void Main(string[] args)
{
MyCallbackClass callbackClass = new MyCallbackClass();
callbackClass.RegisterClient();
}
However, when I do the following below simply by wrapping the above lines inside an button_Click handler in the Winform, this bug manifests itself with a crash:
[STAThread]
private static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
and then have a button click do the rest like so:
private void button1_Click(object sender, EventArgs e)
{
MyCallbackClass callbackClass = new MyCallbackClass();
callbackClass.RegisterClient();
}
then the following bug manifests itself:
1) RequestLogin is called on the server side, but the call to BroadcastToClient never reaches the client. Further to this, the RequestLogin never returns to client side, but instead, will timeout with the following exception:
2) An unhandled exception of type 'System.TimeoutException' occurred in mscorlib.dll. This request operation sent to XXXX did not receive a reply within the configured timeout (00:00:59.6359791). The time allotted to this operation may have been a portion of a longer timeout. This may be because the service is still processing the operation or because the service was unable to send a reply message. Please consider increasing the operation timeout (by casting the channel/proxy to IContextChannel and setting the OperationTimeout property) and ensure that the service is able to connect to the client.
The same behavior occurs if I use a WPF client. On the otherhand, it works perfectly if I use a Console based client!
Why does my Duplex Callback only work outside of a Winform or WPF?
How should I go about resolving this issue?
I am at my witts end here.
Thanks.
Kudos to this individual who has supplied me with an answer:
https://groups.google.com/forum/#!topic/microsoft.public.dotnet.framework.webservices/8Y6C8dRCFws
The solution is to modify MyCallbackClass as follows:
[CallbackBehavior(UseSynchronizationContext = false)]
class MyCallbackClass : IFixContractCallback
{
public void RegisterClient()
{
MyCallbackClass tester = this;
InstanceContext context = new InstanceContext(this);
FixContractClient proxy = new FixContractClient(context);
proxy.Requestlogin("hello");
}
public void BroadcastToClient(string eventData)
{
}
}

Resources