I have a stored procedure that does quite a bit of joins. The query though runs pretty fast, around 3 seconds. I just cant figure out the below error poping up every once in a while. I event cache the document that uses this query for a minute so it doesnt get ran over and over. I am using Entity Framework 5, and my stored procedure is using a CTE to do the paging. Any clues or insight?
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 (0x80004005): The wait operation timed out
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
at System.Data.SqlClient.SqlDataReader.get_MetaData()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader()
at System.Data.Objects.ObjectContext.ExecuteStoreQueryInternal[TElement](String commandText, String entitySetName, MergeOption mergeOption, Object[] parameters)
at System.Data.Objects.ObjectContext.ExecuteStoreQuery[TElement](String commandText, Object[] parameters)
at System.Data.Entity.Internal.InternalContext.ExecuteSqlQuery[TElement](String sql, Object[] parameters)
at System.Data.Entity.Internal.InternalContext.ExecuteSqlQueryAsIEnumerable[TElement](String sql, Object[] parameters)
at System.Data.Entity.Internal.InternalContext.ExecuteSqlQuery(Type elementType, String sql, Object[] parameters)
at System.Data.Entity.Internal.InternalSqlNonSetQuery.GetEnumerator()
at System.Data.Entity.Internal.InternalSqlQuery`1.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Tournaments.Data.Repositories.Games.GamesRepository.GetGamesPaged(IGamesCriteria criteria)
Entity Framework Method
public PagedResult<GameComplex> GetGamesPaged(IGamesCriteria criteria)
{
var results = DataContext.Database.SqlQuery<GameComplex>("EXEC [Schema].[Database] #Page, #PageSize, #SortOrder, #SortDirection, #EventId, #DivisionId, #DivisionTeamId, #Date, #SearchToken, #MemberId",
new SqlParameter("Page", criteria.Page),
new SqlParameter("PageSize", criteria.PageSize),
new SqlParameter("SortOrder", GetDataValue(criteria.SortOrder)),
new SqlParameter("SortDirection", GetDataValue(criteria.SortDirection)),
new SqlParameter("EventId", GetDataValue(criteria.EventId)),
new SqlParameter("DivisionTeamId", GetDataValue(criteria.DivisionTeamId)),
new SqlParameter("DivisionId", GetDataValue(criteria.DivisionId)),
new SqlParameter("Date", GetDataValue(criteria.Date)),
new SqlParameter("SearchToken", GetDataValue(criteria.SearchToken)),
new SqlParameter("MemberId", GetDataValue(criteria.MemberId))).ToList();
return new PagedResult<GameComplex>
{
Page = criteria.Page,
PageSize = criteria.PageSize,
Total = results.Any(q => q != null) ? results.FirstOrDefault().Total : 0,
Results = results
};
}
SQL Server Stored Procedure Parameter Signature
ALTER PROCEDURE [Schema].[Database]
#Page INT = 1,
#PageSize INT = 10,
#SortOrder NVARCHAR(100) = 'Id',
#SortDirection VARCHAR(4) = 'ASC',
#EventId INT = NULL,
#DivisionId INT = NULL,
#DivisionTeamId INT = NULL,
#Date DATETIME = NULL,
#SearchToken NVARCHAR(100) = NULL,
#MemberId INT = NULL
AS
You may need to adjust the COMMAND timeout.
See:
Set Command Timeout in entity framework 4.3
or
How to set CommandTimeout for DbContext?
EDIT
Command Timeout:
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.commandtimeout.aspx
Connection Timeout:
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectiontimeout.aspx
EDIT:
Another possible issue is "parameter sniffing".
http://blogs.msdn.com/b/queryoptteam/archive/2006/03/31/565991.aspx
So try one of the parameter sniffing workarounds:
ALTER PROCEDURE [Schema].[Database]
#Page INT = 1,
#PageSize INT = 10,
#SortOrder NVARCHAR(100) = 'Id',
#SortDirection VARCHAR(4) = 'ASC',
#EventId INT = NULL,
#DivisionId INT = NULL,
#DivisionTeamId INT = NULL,
#Date DATETIME = NULL,
#SearchToken NVARCHAR(100) = NULL,
#MemberId INT = NULL
AS
Declare #PageCopyOf int
Select #PageCopyOf = #Page
Declare #PageSizeCopyOf int
Select #PageSizeCopyOf = #PageSize
Declare #SortOrderCopyOf NVARCHAR(100)
Select #SortOrderCopyOf = #SortOrder
Declare #SortDirectionCopyOf VARCHAR(4)
Select #SortDirectionCopyOf = #SortDirection
Declare #EventIdCopyOf int
Select #EventIdCopyOf = #EventId
Declare #DivisionIdCopyOf int
Select #DivisionIdCopyOf = #DivisionId
Declare #DivisionTeamIdCopyOf int
Select #DivisionTeamIdCopyOf = #DivisionTeamId
Declare #DateCopyOf DATETIME
Select #DateCopyOf = #Date
Declare #SearchTokenCopyOf NVARCHAR(100)
Select #SearchTokenCopyOf = #SearchToken
Declare #MemberIdCopyOf int
Select #MemberIdCopyOf = #MemberId
And then everything below this uses/consumes the #XXXXXCopyOf variable and NOT the original variable (name).
It's worth a try.
Just a guess, but the query runs fast (3 seconds) only when it is cached. Otherwise, it takes a lot longer and exceeds your server timeout setting. Since System.Data.SqlClient is raising the exception, it is likely that the default timeout is only 15 seconds.
MSDN: "The default value is 15 seconds"
Alternatively, try the CommandTimeout property of the SQLCommand object, which defaults to 30 seconds.
CommandTimeout
Related
I am using VS Studio 2105 / SSMS 2014 v 12.0.410. Using VB.net.
I am running a console app that does polling on the 0 and 30 second mark. It will do this 24 by 7. As part of the process, a background thread is spawned. (See explanation below).
The database connection string is:
add key="ConnectionString" value="Server=xxxxx,14334;Database=xxx_dev;Uid=xxx_dev;Password=xxxxxx;MultipleActiveResultSets=true"
The class and its functions called for open and close:
Dim strConnectionString As String = ConfigurationManager.AppSettings("ConnectionString")
Sub OpenDB()
If objConn.State = Data.ConnectionState.Open Then
objConn.Close()
End If
objConn.ConnectionString = strConnectionString
objConn.Open()
objCmd.Connection = objConn
objCmd.CommandType = Data.CommandType.Text
End Sub
Sub CloseDB()
objConn.Close()
End Sub
I customized the error message to get all that I could about it.
A severe error occurred on the current command. The results, if any, should be discarded. --> State: 0 --> Source: .Net SqlClient Data Provider --> Error number: 0 --> Line number: 0 --> Line number: -2146232060 --> Class: 11 --> Procedure: --> Call stack: at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry) at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry) at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() at ReliableSiteBandwidthPollingTester.Module1.SaveBandwidthPollingLog(Switch SaveSwitch, String& strMessage) in C:\Dans\Work 2\Working Area\Switch Polling - design 3\Tester apps\ReliableSiteBandwidthPollingTester\ReliableSiteBandwidthPollingTester\Module1.vb:line 427
The polling process:
It interrogates a network switch gathering data. After the interrogation, it then executes a simple stored procedure 105 times which inserts a row into a table each time. It then starts a background thread which executes a "calculation process" stored procedure that uses the table just inserted into as well as other tables. It does inserts into another table - and potentially deletes. A transaction is used. It either commits or rolls back. However, I believe that the procedure does not finish before the next poll begins - the next 30 second mark.
The simple insert stored procedure has been tested stand alone many times and works fine every time.
The "calculation process" stored procedure has been tested stand alone many times and works fine every time.
I start the console app and it it polls 3 times and the fails with that error. Before failing, it writes the out 3 sets of 105 rows to the table. It also inserts 290 rows into another table as part of the process.
Sub PollSwitch(sender As Object, e As ElapsedEventArgs)
Dim strMessage As String = ""
Dim strPollError As String = ""
Dim bPollResult As Boolean
Dim NetworkSwitch As Switch
' This is the format to display as it is how it is stored in the info log table.
Dim dtFormat As String = "yyyy-MM-dd hh:mm:ss.fff"
If bErrorInThread = True Then
' There was an error in the background thread during the previous issuance of the thread. So do not continue.
strMessage = "Critical Error - in the background thread. See the 'BandwidthInfoLog' table. Refer to this log date: " + dtThreadStartDateTime.ToString(dtFormat)
End If
If strMessage = "" Then
' Create a new instance.
NetworkSwitch = New Switch(strCommandLineSwitchIP, strCommandLineCommunityString)
Try
' Do the switch polling.
bPollResult = NetworkSwitch.Poll(strPollError)
If bPollResult = False Then
strMessage = "Warning - in bandwidth poll. Poll error at " & Now & ": " & strPollError & " Poll will continue."
Else
' Save to the bandwidth polling log.
SaveBandwidthPollingLog(NetworkSwitch, strMessage)
If InStr(strMessage, "Critical") = 0 Then
Console.WriteLine("Successfully polled at " & Now() & ".")
' Set the date/time as it will be used above in an error message should the thread process fail.
dtThreadStartDateTime = Now()
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Now do the "calculation process" - it will be in it's own background thread.
' Note: the thread ends when the ProcessCalculatedSwitchPolling method ends.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim thread As New Thread(AddressOf ProcessCalculatedSwitchPolling)
thread.Start()
End If
End If
Catch ex As Exception
strMessage = "Critical Error - in bandwidth poll - " & ex.Message & "<br /><br />Switch: " & strCommandLineSwitchIP
End Try
End If
If InStr(strMessage, "Critical") > 0 Then
' Stop this method (this poll timer) as there is a critical error.
DisposeTimer()
' Show message.
Console.WriteLine(strMessage)
Console.WriteLine("--------->>>> PRESS ENTER TO QUIT.")
Console.ReadKey()
' Exit the console application here as there is a critical error.
' Normally the exit would occur in the main method when the User hits a key.
Environment.Exit(0)
End If
End Sub
The call stack shows it fails on line 427 which is the .ExecuteNonQuery() line.
Sub SaveBandwidthPollingLog(ByVal SaveSwitch As Switch, ByRef strMessage As String)
Const strFunctionId As String = "VB - savebandwidthpollinglog. Error ID: "
Const iSQLErrorId As Integer = 501
Const iCATCHErrorId As Integer = 502
Dim dtCurrentDateTime As Date = Now()
Dim strProcessInfoLogResult As String = ""
Dim strAdditionalInfoForLog As String = ""
' This is the format to display as it is how it is stored in the info log table.
Dim dtFormat As String = "yyyy-MM-dd hh:mm:ss.fff"
DBFunc.OpenDB()
Try
With DBFunc.objCmd
.CommandType = Data.CommandType.StoredProcedure
.CommandText = "InsertBandwidthLogTest6"
' Note: it was timing out, so the SqlCommand.CommandTimeout property has expired; the default timeout is 30 seconds.
.CommandTimeout = 0
For Each SavePort In SaveSwitch.Port
.Parameters.Clear()
.Parameters.AddWithValue("#SwitchIP", SaveSwitch.IP)
.Parameters.AddWithValue("#PortIndex", SavePort.Index)
.Parameters.AddWithValue("#PortSpeed", SavePort.Speed)
.Parameters.AddWithValue("#InOctets", SavePort.InOctets)
.Parameters.AddWithValue("#OutOctets", SavePort.OutOctets)
.Parameters.AddWithValue("#TimeStamp", SavePort.TimeStamp)
.ExecuteNonQuery()
Next
End With
Catch sqlex As SqlException
' Its a critical issue.
If InStr(sqlex.Message, "Critical") > 0 Then
' Coming from the stored procedure.
strMessage = sqlex.Message
Else
strProcessInfoLogResult = ProcessInfoLog(dtCurrentDateTime, sqlex.Message + " --> State: " + sqlex.State.ToString() + " --> Source: " + sqlex.Source + " --> Error number: " + sqlex.Number.ToString() + " --> Line number: " + sqlex.LineNumber.ToString() + " --> Line number: " + sqlex.HResult.ToString() + " --> Class: " + sqlex.Class.ToString() + " --> Procedure: " + sqlex.Procedure + " --> Call stack: " + sqlex.StackTrace, strAdditionalInfoForLog, strFunctionId, iSQLErrorId)
End If
Catch ex As Exception
strProcessInfoLogResult = ProcessInfoLog(dtCurrentDateTime, ex.Message, strAdditionalInfoForLog, strFunctionId, iCATCHErrorId)
Finally
' Close database.
DBFunc.CloseDB()
End Try
End Sub
The Thread process:
Public Sub ProcessCalculatedSwitchPolling()
Const strFunctionId As String = "VB - processcalculatedswitchpolling. Error ID: "
Const iSQLErrorId As Integer = 601
Const iCATCHErrorId As Integer = 602
Dim strProcessInfoLogResult As String = ""
Dim strAdditionalInfoForLog As String = ""
Dim strInputParms As String = ""
' Set for the error log.
strInputParms = "S/P parmameters - switch IP Address: " & strCommandLineSwitchIP
DBFunc.OpenDB()
Try
With DBFunc.objCmd
.CommandType = Data.CommandType.StoredProcedure
.CommandText = "ProcessBandwidthLogCalculatedTest6"
' Note: it was timing out, so the SqlCommand.CommandTimeout property has expired; the default timeout is 30 seconds.
.CommandTimeout = 0
.Parameters.Clear()
.Parameters.AddWithValue("#SwitchIP", strCommandLineSwitchIP)
.ExecuteNonQuery()
End With
Catch sqlex As SqlException
' Its a critical issue.
If InStr(sqlex.Message, "Critical") > 0 Then
' Coming from the stored procedure.
' Set the global variable - the thread error indicator.
bErrorInThread = True
Else
' Not coming from the stored procedure.
bErrorInThread = True
' Log the exception as it was not logged in the stored procedure.
strAdditionalInfoForLog = strInputParms
strProcessInfoLogResult = ProcessInfoLog(dtThreadStartDateTime, sqlex.Message, strAdditionalInfoForLog, strFunctionId, iSQLErrorId)
End If
Catch ex As Exception
bErrorInThread = True
' Log the exception.
strAdditionalInfoForLog = strInputParms
strProcessInfoLogResult = ProcessInfoLog(dtThreadStartDateTime, ex.Message, strAdditionalInfoForLog, strFunctionId, iCATCHErrorId)
Finally
' Close database.
DBFunc.CloseDB()
End Try
End Sub
In production I had an episodic timeout exception during commit an Nhibernate transaction. But the records that I expect updated are correct!
In stage environment nothing to report.
Here below the application logs of my batch program.
ERROR 2015-06-25 01:32:01,165 SRV-IIS03 Commit failed
System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest(Byte[] buffer, TransactionManagerRequestType request, String transactionName, TransactionManagerIsolationLevel isoLevel, Int32 timeout, SqlInternalTransaction transaction, TdsParserStateObject stateObj, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(Transacti onRequest transactionRequest, String transactionName, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction(TransactionReq uest transactionRequest, String name, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalTransaction.Commit()
at System.Data.SqlClient.SqlTransaction.Commit()
at NHibernate.Transaction.AdoTransaction.Commit()
ERROR 2015-06-25 01:32:01,431 SRV-IIS03 Errore imprevisto nel metodo Run:NHibernate.TransactionException: Commit failed with SQL exception ---> System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest(Byte[] buffer, TransactionManagerRequestType request, String transactionName, TransactionManagerIsolationLevel isoLevel, Int32 timeout, SqlInternalTransaction transaction, TdsParserStateObject stateObj, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(TransactionRequest transactionRequest, String transactionName, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction(TransactionRequest transactionRequest, String name, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalTransaction.Commit()
at System.Data.SqlClient.SqlTransaction.Commit()
at NHibernate.Transaction.AdoTransaction.Commit()
--- End of inner exception stack trace ---
at NHibernate.Transaction.AdoTransaction.Commit()
at [omit].Run(String[] args) in [omit].cs:line 153
ERROR 2015-06-25 01:32:01,493 SRV-IIS03 Errore imprevisto nel batch [omit]: NHibernate.TransactionException: Transaction not successfully started
at NHibernate.Transaction.AdoTransaction.CheckBegun()
at NHibernate.Transaction.AdoTransaction.Rollback()
at [omit].RollbackTransazione() in [omit].cs:line 212
at [omit].Run(String[] args) in [omit].cs:line 159
at [omit].Main(String[] args) in [omit].cs:line 29
And here below the structure of my batch
private static ITransaction tx;
public virtual BatchResponseStatus Run(string[] args)
{
var response = BatchResponseStatus.Success;
try
{
//Do some stuff
SetTransaction();
//Collect elements to be processed
foreach (var item in aListOfItem)
{
// Stuff
// Call methods that creates, reads or updates records
// with Fluent Nhibernate or Sql Server Stored procedure
// Write some files
// Zip files
// Update DTO
}
tx.Commit();
}
catch (Exception ex)
{
RollbackTransaction();
XXRepository.NhSession.Clear();
response = BatchResponseStatus.Error;
}
finally
{
DisposeTransaction();
}
return response;
}
private void SetTransaction()
{
tx = XXRepository.NhSession.BeginTransaction(IsolationLevel.ReadUncommitted);
if (tx == null)
throw new Exception("Impossible create a Transaction");
}
private static void RollbackTransaction()
{
if (tx != null)
{
tx.Rollback();
}
}
I use this technologies:
Sql Server stored procedure
Nhibernate 3.4 (Fluent Nhibernate)
.Net Framework 4.5
Anybody can help me?
Thanks.
The timeout occurs on the connection. This means, that the connection times out, but commit continues in Sql Server. As you can see in the log, Rollback fails because the connection is already committed. IMHO, the connection timeout is not properly handled by the SqlClient implementation.
There is a forum thread where this is discussed.
Query is sum up the top 500 account balances grouped by currencies, used in comparison query from a new SQL 2012 server and existing server to validate no changes in the new 2012 server.
Set timeout property to |set option|command|900| and to no avail.
Below is extract of the error:
System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlDataReader.SetMetaData(_SqlMetaDataSet metaData, Boolean moreInfo)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
at System.Data.SqlClient.SqlDataReader.get_MetaData()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet)
at dbfit.DatabaseTest.GetDataTable(Symbols symbols, String query, IDbEnvironment environment, Int32 rsNo)
at dbfit.fixture.StoreQuery.DoTable(Parse table)
at fitSharp.Fit.Operators.InterpretFlow.DoTable(Tree`1 table, Interpreter activeFixture, Boolean inFlow)
I've attempted to reduce the number of rows to check to 300 from 500 and that seems to work, however a large dataset would be ideal to highlight any discrepancies.
I'm also looking into changing the query to something else to either break it up to a smaller resultset or create an alternative
The query is below, if anyone has a better solution to optimise the query:
select
TOP 1000 fab.DateKey,be.BK_ActOId,be.PtId,be.PDesc,
be.OId,be.ODesc,be.SubOId,be.SubODesc,
rc.Currency,SUM(CASE WHEN rc.Currency = '_NA' THEN FAB.Balance ELSE 0 END) as bal_OrigCcy
,SUM(CASE WHEN rc.Currency = 'AUD' THEN FAB.Balance ELSE 0 END) as bal_AUD
,SUM(CASE WHEN rc.Currency = 'GBP' THEN FAB.Balance ELSE 0 END) as bal_GBP
,SUM(CASE WHEN rc.Currency = 'SGD' THEN FAB.Balance ELSE 0 END) as bal_SGD
,SUM(CASE WHEN rc.Currency = 'USD' THEN FAB.Balance ELSE 0 END) as bal_USD
from olap.v_FactAccB fab
inner join OLAP.v_DimCur dc on dc.CurrencyKey = fab.BalanceCurrencyKey
inner join olap.v_DimReportingCur rc on rc.CurrencyKey = fab.ReportingCurrencyKey
inner join OLAP.v_DimBusinessEntity be on be.BusinessEntityKey = fab.BusinessEntityKey
and rc.Currency in ('_NA', 'AUD', 'GBP', 'SGD','USD')
and fab.DateKey = 20130912
and fab.PlatformKey = 1
group by fab.DateKey, be.BK_ActOId, be.PId, be.PDesc
,be.OId, be.ODesc, be.SubOId, be.SubODesc, rc.Currency
order by fab.DateKey, be.BK_ActOId, be.PId, be.PDesc, be.OId, be.ODesc, be.SubOId, be.SubODesc, rc.Curr
Does anyone have alternatives other than the one above
I would rewrite your query to use a PIVOT instead of the repeated SUM(CASE... )
eg:
select * from yourtable
pivot (SUM(balance) for currency in (_NA,AUD,GBP,SGD,USD)) p
We're using EntityFramework in a project that just went live. According to our logs, several users are suffering from "Invalid operation. The connection is closed", it happends about 50 times per day.
Exception looks like:
An error occurred while executing the command definition. See the inner exception for details. at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
at System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at xxxx.SelectResultToPeople(IEnumerable`1 result)
at xxxx.GetResult()
at DynamicModule.ns.Wrapped_IPeopleGetter_a853d13914444ca6ab0e016e035520c5.<People_DelegateImplementation>__0(IMethodInvocation inputs, GetNextInterceptionBehaviorDelegate getNext)
Invalid operation. The connection is closed. at System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync()
at System.Data.SqlClient.TdsParserStateObject.TryReadNetworkPacket()
at System.Data.SqlClient.TdsParserStateObject.TryPrepareBuffer()
at System.Data.SqlClient.TdsParserStateObject.TryReadByte(Byte& value)
at System.Data.SqlClient.TdsParserStateObject.TryPeekByte(Byte& value)
at System.Data.SqlClient.SqlDataReader.TrySetMetaData(_SqlMetaDataSet metaData, Boolean moreInfo)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlDataReader.TryCloseInternal(Boolean closeReader)
at System.Data.SqlClient.SqlDataReader.Close()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
This exception is thrown on very specific pages, so it's not randomly distributed across the application. One of these pages makes a simple query to the database through Entity framework using a table function. The table function is named "GetPeopleNames" and our ObjectContext class is the one named "SiteEntities".
public class PeopleGetter : IPeopleGetter
{
public List<object> GetResult()
{
using (var siteEntities = new SiteEntities())
{
IQueryable<someResultEntity> result =
siteEntities.GetPeopleNames()
.SortBy("Name", "asc")
.Skip(20*query.CurrentPagingPosition)
.Take(20);
List<People> people = SelectResultToPeople(result)
return people;
}
}
private List<People> SelectResultToPeople(IQueryable<someResultEntity> result)
{
return result
.ToList()
.Select(x => new People { })
.ToList();
}
}
I can't see why it should have something to do with our fault, but i'd better mention that PeopleGetter class is resolved and created by Unity IoC container. The PeopleGetter is registered with a 'PerRquest' LifeTimeManager like this:
public class PerCallContextLifeTimeManager : HierarchicalLifetimeManager
{
private readonly string _key = string.Format("PerCallContextOrRequestLifeTimeManager_{0}", Guid.NewGuid());
public override object GetValue()
{
if (HttpContext.Current != null)
return GetFromHttpContext();
else
return base.GetValue();
}
private object GetFromHttpContext()
{
return HttpContext.Current.Items[_key];
}
public override void SetValue(object newValue)
{
if (HttpContext.Current != null)
SetInHttpContext(newValue);
else
base.SetValue(newValue);
}
private void SetInHttpContext(object newValue)
{
HttpContext.Current.Items.Add(_key, newValue);
}
public override void RemoveValue()
{
}
}
Any ideas why we're getting closed connections?
Thanks for you help!
When I try to run this i get an SqlException with the message "Incorrect syntax near the keyword 'PROCEDURE'."
120: cmd.CommandText = #"CREATE PROCEDURE FindState #Name nvarchar(50)
AS SELECT IDState FROM State WHERE Name=#Name";
121: cmd.ExecuteNonQuery();
Stack trace:
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at xxx.Program.Main(String[] args) in C:\xxx\Program.cs:line 121
However I tried copying the SQL command directly in a SQL query and executing it and it worked. (it created the procedure)
To give you some context here is a little bigger section of the code
SqlParameter stateName = new SqlParameter();
stateName.SqlDbType = SqlDbType.NVarChar;
stateName.Direction = ParameterDirection.Input;
stateName.ParameterName = "#Name";
stateName.Size = 50;
Console.Write("Enter state name: ");
stateName.Value = Console.ReadLine();
cmd.Parameters.Add(stateName);
cmd.CommandText = #"IF EXISTS (SELECT name FROM sysobjects WHERE name='FindState' AND type='P') DROP PROCEDURE FindState";
cmd.ExecuteNonQuery();
cmd.CommandText = #"CREATE PROCEDURE FindState
#Name nvarchar(50)
AS
SELECT IDState FROM State WHERE Name=#Name";
cmd.ExecuteNonQuery();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "FindState";
sdr = cmd.ExecuteReader();
if (sdr.HasRows)
{
while (sdr.Read())
{
Console.WriteLine("ID state " + stateName.Value + " is " + sdr[0]);
}
}
else
{
Console.WriteLine("No such state exists");
}
sdr.Close();
try this:
SqlParameter stateName = new SqlParameter();
stateName.SqlDbType = SqlDbType.NVarChar;
stateName.Direction = ParameterDirection.Input;
stateName.ParameterName = "#Name";
stateName.Size = 50;
Console.Write("Enter state name: ");
stateName.Value = Console.ReadLine();
cmd.Parameters.Add(stateName);
cmd.CommandText = "IF EXISTS (SELECT name FROM sysobjects WHERE name='FindState' AND type='P') DROP PROCEDURE FindState";
cmd.ExecuteNonQuery();
cmd.CommandText = "CREATE PROCEDURE FindState
#Name nvarchar(50)
AS
BEGIN
SELECT IDState FROM State WHERE Name=#Name";
END
cmd.CommandType = CommandType.StoredProcedure;
cmd.ExecuteNonQuery();
cmd.CommandText = "FindState";
sdr = cmd.ExecuteReader();
if (sdr.HasRows)
{
while (sdr.Read())
{
Console.WriteLine("ID state " + stateName.Value + " is " + sdr[0]);
}
}
else
{
Console.WriteLine("No such state exists");
}
sdr.Close();
I figured out what the problem was.
The parameter was added to the SqlCommand before creating the procedure.
I moved this line down and now it works
cmd.CommandText = #"CREATE PROCEDURE FindState #Name nvarchar(50) AS SELECT IDState FROM State WHERE Name=#Name";
cmd.ExecuteNonQuery();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "FindState";
cmd.Parameters.Add(stateName);
sdr = cmd.ExecuteReader();