I am using NHibernate with mySQL 5 and I am a bit unsure whether NHibernate really closes the connection to mySQL.
This is the code I am using in order to save a Player entity to the database:
using (ISession session = SessionFactory.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
session.Save(player);
transaction.Commit();
}
}
After running this piece of code, I select the current connection count from the mySQL server using
show status like 'Conn%' ;
and the value is increased every time by 1!
So, inserting the player 10 times (=starting the program 10 times) increases the connection count by 10. But the session.IsClosed property of the NHibernate Session is false.
Do I have to do anything else in order to release the NHibernate resources and close the connection? Are the connections pooled / timed out?
It would be great if anyone could give me a hint.
I'm pretty sure the Connection is being closed. The dispose method on the ISession does just that. So it's unlikely it remains open when exiting the using block.
Also , from what I know the connection is usually opened only when writing/reading to the database . The session may be open, but that doesn't mean the connection is also open.
That, plus the fact that in the mysql documentation, it says that the keyword Connections means :
The number of connection attempts (successful or not) to the MySQL server.
and doesn't say anything about the current state of the connection (open or not), makes me believe that the connection is closed.
PS: you should be using Threads_connected to see open connections.
There is a bug in the MySQL.Data dll in certain versions that was causing this same problem for me. Make sure you update your Connector/NET to the most recent. This solved the problem for me.
Related
I’m trying to develop a server for a mobile game which should be able to withstand 1000 simultaneous connections. The Server is connected to a MySQL Database and each time I am looking to access the database I enclose my SQLConnection Cmd and Reader with a using statement so that they are all opened briefly and closed afterwards:
using (MySqlConnection SQLToUse = CreateSQLConnection()) {
MySqlCommand cmd = new MySqlCommand(query, SQLToUse);
...
}
I had problems with readers which is why I had to do this.
Theoretically, if say 1000 users were to open SQL Connections simultaneously, the maximum amount of SQL connections (151 to my knowledge) would stop me from creating any more connections and throw an error. This hasn’t happened yet because the highest number of users the server ever had at once was 10, but i am asking how to prevent it.
Thank you for reading this all the way through and for your help in advance
What you need to do is to create a service part that keep the connection(s) open and then the other part of the game make requests to this part. (sort of how you use a library)
I would also suggest you add a stack and each time a query is done it can check the stack for another query to run. Each time something is added to the stack, check if there is any connections available, if there are activate a connection that will pick up the new line in the stack.
Very hard to describe the code with no information on what languages is used but this should get you in the right direction.
My app is working with MySQL database, to connection I'm using FireDAC components. Last time I have got a network problem, I test it and it is looks like (time to time) it losing 4 ping request. My app return me error: "[FireDAC][Phys][MySQL] Lost connection to MySQL server during query". Now the question: setting fdconnection.TFDUpdateOptions.LockWait to true (default is false) will resolve my problem or make new problems?
TFDUpdateOptions.LockWait has no effect on your connection to the database. It determines what happens when a record lock can't be obtained immediately. The documentation says it pretty clearly:
Use the LockWait property to control whether FireDAC should wait while the pessimistic lock is acquired (True), or return the error immediately (False) if the record is already locked. The default value is False.
The LockWait property is used only if LockMode = lmPessimistic.
FireDAC can't wait to get a lock if it loses the connection, as clearly there is no way to either request the lock or determine if it was obtained. Therefore, changing LockWait will not change the lost connection issue, and it may slow many other operations against the data.
The only solution to your lost ping requests is to fix your network connection so it stops dropping packets. Simply randomly changing options on TFDConnection isn't going to fix networking issues.
When you run a basic ColdFusion query, when does ColdFusion actually log out of the database? When does the query actually close? My understanding is that when you have multiple users being authenticated at the same time, it maintains it's connection and uses a new thread for a new user. But I am struggling to find any documentation as to when it actually closes. Is it when the page is finished rendering or is it directly after the query execution?
Any help on this matter would be greatly appreciated. We are running ColdFusion 9 Standard with SQL Server 2008.
My understanding it that, by default, ColdFusion won't log out of the database at a particular time. It uses a connection pool, so when you make a query, coldfusion takes a connection from it's pool of connections (creating a connection if none were present), executes the query, then hands the connection back to the pool, ready for more requests. Connections will eventually be closed when they've been inactive for long enough (20 minutes by default, set by the Timeout setting in ColdFusion DataSource admin).
I think the strict answer to your question is: 20 minutes since the last use of that connection, but that's hard to determine
As a standard procedure, MySql connection is lost after stated number of hours (default:8) of inactivity. To reconnect to the mysql server after identifying such connection lost I simply do connection = DriverManager.getConnection(url, user, password);
I am not using connection pool and as this trick has not been mentioned in previous connection lost related posts, that makes me wonder if my code will generate any side-effects later? (I say so because testing this code after above instance, I found the sessionlistner is not called after session.invalidate() call.)
You'll loose temporary tables and session settings if your connection drops. It sounds like a connection pool would be useful in your situation.
Depending on how you handle connection object(s), it can create small client-side memory leak for connection object that was lost. But probably this effect will be so small that you will never see any problems from it.
To minimize this risk, you can do something as simple as SELECT 1 every few minutes from your connection during idle time, such that your connection is still considered active (unless your client dies off completely).
I have an application which connects to a MySql database using Delphi's TAdoConnection object. This is a very query intensive application. So I create the connection and keep it open to avoid the high resource expense of open/closing database connections. But obviously problems can arise (database restart, network connection failure, etc). So I have built in code to free my database object, recreate it, and reconnect when queries fail.
I have a common function to connect to the database. The relevant code is this:
try
AdoConnection.open;
result := Adoconnection.Connected
except
result := False;
......
end;
I ran some test by turning on and off the MySql database. Everything works fine if the database is off on application startup (i.e. it properly throws an exception). However, if I turn off the database after the application has already successfully connected, subsequent re-connections do not throw exceptions, and additionally falsley report true for AdoConnection.Connected. I am sure the connection object had been freed/recreated first.
It seems there is some sort of caching mechanism going on here (most likely at the hardware/driver level - not application level). Anyone have any ideas?
I observed this also.
Ideas for dealing with it:
If you get an error on running a query then check if it's a connection issue and if so try to reconnect and then run the query again.
If your program uses a timer and waits a while between running batches of queries then perform a simple query (maybe "select now()") before each batch and if this fails then try to reconnect.