sleeping awaiting command blocks other transactions - asp.net

I have a big web application on asp.net 2.0.
Usere open object editor there and makes some changes. They can not open the same object at one time.
After they press "save" btn all changes process to save on server via postback.
I am using transaction for save. There are a lot of procedures, checks and others to be done before saving operation is OK.
using (SqlConnection con = .........)
{
SqlTransaction trans = null;
try
{
con.Open();
trans=con.BeginTransaction(IsolationLevel.ReadUncommitted);
........operations.........
trans.Commit();
}
catch (Exception e)
{
try { if (trans != null) trans.Rollback(); }
catch { }
throw new MyException("SQL Exception: " + e.Message, e);
}
finally
{
if (con != null && con.State == ConnectionState.Open) con.Close();
}
}
For me this code is quite safe.
But periodicaly happens:
one process from this web application on saving operation on mssql became "sleeping/awaiting".
and others processes called by other users became locked by this process and organiza a queue.
One of them threw timeout excetion.....but others are waiting.
So, my question is: does my code have some bad operation that allows command to became sleeping/awaiting?
May be there are some tricks?

Since you are doing a lot DB of operations inside a transaction there is a chance that a database lock is blocking your application.
You can use the sp_who2 stored procedure (there are more details on it here) to see if there any blocks on your server, by checking the BlkBy column of the result.
You might also want to check the following links on Sql Server locks and deadlocking

Может ли это быть связано с репликацией. В момент когда наблюдаются описанные выше тормоза репликация начинает сильно тормозить. И пишет:
The process could not connect to Publisher 'эта бд'. (Source: MSSQL_REPL, Error number: MSSQL_REPL20084)
Get help: http://help/MSSQL_REPL20084
· TCP Provider: 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. (Source: MSSQLServer, Error number: 10060)
Get help:
· An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (Source: MSSQLServer, Error number: 10060)
Get help:
· Login timeout expired (Source: MSSQLServer, Error number: 0)
Get help:
· The merge process failed to execute a query because the query timed out. If this failure continues, increase the query timeout for the process. When troubleshooting, restart the synchronization with verbose history logging and specify an output file to which to write. (Source: MSSQLServer, Error number: 0)
Get help:
Эта БД является источником репликации.

But the main problem is that the first process does not threw timeout exception. It is sleeping as log as we do not kill him. That is the main problem.

Related

Having trouble connecting to iSeries from .NET Core

This is a follow-up from the following question: Having trouble connecting to iSeries from .NET Core
The initial problem was resolved by setting a port number. I'm now running into the problem of the connection seemingly opening, however, hanging on the actual .Open() step - IE, never continuing on to the next line of code. For reference, here's my code block:
public static DB2Connection GetDatabaseConnection(string connectionString)
{
DB2Connection DB2Connection = new DB2Connection(connectionString);
DB2Connection.SystemNaming = true;
try
{
DB2Connection.Open();
return DB2Connection;
}
catch (Exception ex)
{
throw ex;
}
}
And my connection string is in this format: Server=###.###.###.###:#####;Database=DATABASE;UID=USER;PWD=PASSWORD;LibraryList=LIBRARY,LIST
Looking at the logs on the i Navigator, I see that there is a job name Qzhqssrv when is opened, with the user Quser, status Running, and type Prestart batch - Server. Looking into the logs for that entry, I see Job #####/QUSER/QZHQSSRV started on DATE at TIME in subsystem QUSRWRK in QSYS. Job entered system on DATE at TIME. However, it doesn't seem to continue beyond that.
Looking at the logs for a similar operation, when I'm connecting via Access Client Solutions, I get considerably more information and more steps in the logs. This leads me to believe that the system is waiting for me to send further information, however, my application is still stuck on .Open() - so perhaps there is something else I was supposed to send as part of the .Open() instruction. If so, I'm not sure what it would be.
Any insights would be greatly appreciated. Thanks!
Just to close this topic out - the problem was indeed the lack of a license. Connecting on port 446 was the correct approach, and once we got a license, we were able to get the connection working. Thanks #nfgl!

JMS - Cannot retrieve message from queue. Happens intermittently

We have a Java class that listens to a database (Oracle) queue table and process it if there are records placed in that queue. It worked normally in UAT and development environments. Upon deployment in production, there are times when it cannot read a record from the queue. When a record is inserted, it cannot detect it and the records remain in the queue. This seldom happens but it happens. If I would give statistic, out of 30 records queued in a day, about 8 don't make it. We would need to restart the whole app for it to be able to read the records.
Here is a code snippet of my class..
public class SomeListener implements MessageListener{
public void onMessage(Message msg){
InputStream input = null;
try {
TextMessage txtMsg = (TextMessage) msg;
String text = txtMsg.getText();
input = new ByteArrayInputStream(text.getBytes());
} catch (Exception e1) {
// TODO Auto-generated catch block
logger.error("Parsing from the queue.... failed",e1);
e1.printStackTrace();
}
//process text message
}
}
Weird thing we cant find any traces of exceptions from the logs.
Can anyone help? by the way we set the receiveTimeout to 10 secs
We would need to restart the whole app for it to be able to read the records.
The most common reason for this is the listener thread is "stuck" in user code (//process text message). You can take a thread dump with jstack or jvisualvm or similar to see what the thread is doing.
Another possibility (with low volume apps like this) is the network (most likely a router someplace in the network) silently closes an idle socket because it has not been used for some time. If the container (actually the broker's JMS client library) doesn't know the socket is dead, it will never receive any more messages.
The solution to the first is to fix the code; the solution to the second is to enable some kind of heartbeat or keepalives on the connection so that the network/router does not close the socket when it has no "real" traffic on it.
You would need to consult your broker's documentation about configuring heartbeats/keepalives.

Connection pooling - closed connection issue

Problems:
I have a web app that is getting battered. Everything is working but I get about two errors a day I can not explain. It could be the first user hitting the system because the error appears in the error log intermittently it occurred today around 7:30 am in servers time zone (same as the users).
I fixed an old issue by implicitly destroying the connection by way of the using statement as it only marks the connection as recyclable.
Error Log:
Message: 3df8d62a-6b47-479e-b5d2-b23e0db92d92 : System.InvalidOperationException: Invalid operation. The connection is closed.
at System.Data.SqlClient.SqlConnection.GetOpenConnection()
at System.Data.SqlClient.SqlConnection.get_ServerVersion()
at System.Data.Linq.SqlClient.SqlProvider.get_IsServer2005()
at System.Data.Linq.SqlClient.SqlProvider.InitializeProviderMode()
at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query)
at System.Data.Linq.DataQuery`1.System.Linq.IQueryProvider.Execute[S](Expression expression)
at System.Linq.Queryable.SingleOrDefault[TSource](IQueryable`1 source)
at xxxxx.Resources.Data.LINQ.DistrictService.GetDistrict(Int32 districtID)
Related Code:
//--------------------------------------------------------------------------------------------
public Domain.Data.District GetDistrict(int districtID)
{
using (_dataContext = new DistrictDataDataContext(_systemService.GetCurrentSystem().WriteOnlyDatabase.ConnectionString))
{
Mapper.CreateMap<District, Domain.Data.District>();
return (from s in _dataContext.Districts
where s.DistrictID == districtID
select Mapper.Map<District, Domain.Data.District>(s)).SingleOrDefault();
}
}
Note:
I think that this is a non-issue because the inherent behavior of the connection pooling might be firing a retry (this could just be information saying "hey we tried what you asked for but the connection was closed, we will now open one up it.") however, If this is the case, I do not get a confirmation of successful retry and I am not even sure would be expected. We have had no complaints and this cant be duplicated in house by our QA staff. I hope maybe someone else has come across this.

How to Rollback SQL transaction in between a try-catch block in ASP.Net?

I am executing a Submit routine in ASP.Net. The problem is, while debugging the code in try-catch block, if I/user encounters an error, the SQL Transaction never rollbacks.
SQL Server 2008 hangs totally if I break this submit routine in between. I am unable to do Select/Insert operations even from SSMS. At the end, i have to restart SQL Server in order to rollback the transactions.
Code for submit:
SqlConnection conn = Db.getConn();
if (conn.State == ConnectionState.Closed) conn.Open();
SqlTransaction trn;
trn = conn.BeginTransaction();
SqlCommand sqlCmd = new SqlCommand("", conn);
sqlCmd.Transaction = trn;
try
{
string query = GetQuery(); // works fine
sqlCmd.CommandText = query;
sqlCmd.ExecuteNonQuery();
using (SqlBulkCopy bcp = new SqlBulkCopy(conn,SqlBulkCopyOptions.Default, trn))
{
bcp.ColumnMappings.Add("FaYear", "FaYear");
bcp.ColumnMappings.Add("CostCode", "CostCode");
bcp.ColumnMappings.Add("TokenNo", "TokenNo");
bcp.DestinationTableName = "ProcessTokenAddress";
bcp.WriteToServer(globaltblAddress.DefaultView.ToTable());
}
trn.commit();
}
catch (SqlException ex)
{
trn.Rollback();
}
NOTE: Just while writing the code here, i realized i have catched SqlException and not Exception. Is that what is causing the error? phew?
IMPORTANT: Do i need to rollback the transaction in Page_UnLoad or some other event handler which could handle unexpected situations (for eg. user closes the browser while the transaction is in progress, user hits back button etc).
First, in .Net you shouldn't be maintaining a single open connection which you reuse over and over. The result of this is actually exactly what you're experiencing—in a situation where a connection should be closed, it isn't.
Second, connections implement IDisposable. This means they should be created, and used, within a using statement, or a try-catch block with a finally that explicitly closes the connection. You can break this rule if you have a class that itself implements IDisposable and holds onto the connection for its own lifetime, then closes the connection when it is disposed.
You might be tempted to think that you're increasing efficiency by not opening and closing connections all the time. In fact, you'd be mistaken, because .Net deals with connection pooling for you. The standard practice is for you to pass around connection strings, not open connection objects. You can wrap a connection string in a class that will return a new connection for you, but you shouldn't maintain open connections. Doing so can lead to errors just such as you have experienced.
So instead, do these things:
Use a using statement. This will properly clean up your connections after creating and using them.
using (SqlConnection conn = Db.getConn()) {
conn.Open();
// your code here
}
The fact that you have to check whether the connection is open or not points to the problem. Don't do this. Instead, change your code in your Db class to hand out a newly-created connection every time. Then you can be certain that the state will be closed, and you can open it confidently. Alternately, open the connection in your Db class, but name your method to indicate the connection will be open such as GetNewOpenConnection. (Try to avoid abbreviation in method and class names.)
I would recommend that you throw the error. While logging it and not throwing it is a possible option, in any context where a user is sitting at a computer expecting a result, simply swallowing the error will not be the correct action, because then how will your later code know that an error occurred and let the user know? Some means of passing the exception information on to the user is necessary. It's better to not handle the exception at all than to swallow it silently.
Finally, a little style note is that getConn() does not follow the normal capitalization practices found in the C# community and recommended by Microsoft. Public methods in classes should start with a capital letter: GetConn().

The timeout period elapsed prior to obtaining a connection from the pool

I'm getting this error every few days. I won't see the error for a few days then I'll get a flurry of 20 or so all with in a minute or so.
I've been very thorough going throw my code so that I'm using this basic setup for my DB access.
try
{
myConnection.Open();
mySqlDataAdapter.Fill(myDataTable);
myConnection.Close();
}
Catch (Exception err)
{
if (myConnection.State != ConnectionState.Closed) myConnection.Close();
throw err;
}
The way I understand it this should execute my queries and immediately release the connection back to the pool but if something goes wrong with the query then I catch the excpetion close my connection then throw the error up, which eventually gets trapped at the application level and logs and emails me the error.
Even using this throughout my code I'm still running across the issue. What can I do to diagnose the root cause of the issue?
The issue is the number of pooled connections you can have in the pool.
In your connection string, you can add the
"Max Pool Size=100"
attribute to increase the size of your pool. However it sounds like you are concurrently running a significant number of SQL queries, all of which are long running. Perhaps you should look at ways to either shorten the queries or run them sequentially through a single connection.
changing the code to something like this makes it easier to read..
try
{
myConnection.Open();
mySqlDataAdapter.Fill(myDataTable);
}
Catch (Exception err)
{
throw err;
}
finally
{
myConnection.Close();
}
But it doesn't help your timeout..
It sound like the fill statement takes to long. Or that the problem actually is somewhere else, where you don't the connection.
SQL Profiling could help figuring out if the select statement takes to long..
A quick question here. Are you by chance on an access DB because there is a limit on the number of connections that you can concurrently have on it which would result in your type of error. SQL serve shouldn't have the same problem.
if you are runing SQL server then turn off connection pooling and see if it makes a difference to your app.
I found out with our system about 5 years ago when our company was rapidly growing that we basically broke access when we started constantly hitting the user cap. We switched to SQL in about 24 hours and haven't had a problem since.
If you're using MSSQL set up a profile running for sometime a day or two..
Make the profile to be saved to a file or a table, file is supposed to be faster...
And then having a script reading that file to a table you could easily query it to find the longest running queries.

Resources