I have a test console app that is executing sql scripts to create a database and its tables, then inserting data. I use DAO to create, retrieve, update, and delete from the tables and then try and drop the database, but it can't because it says it is currently in use. How do I kill the connection? Through debugging and running a sql script to see the total connections, I've narrowed it down to this piece of code that is not killing the connection. Even though it says the connections are cleared, the database says it is still connected.
foreach (ISessionFactory factory in this.connections.Values)
{
factory.Close();
}
this.connections.Clear();
this.connections = null;
NHibernate manages all the database connections itself. It opens and closes the database as it sees fit, but you can try to call Session.Disconnect to get it to disconnect from the ADO.NET connection.
However ... if you have Connection Pooling enabled, which is normally the 'default' connection behavior, the connection will only be returned to the connection pool, not released, and it will still show as a connection, so you would have to clear the connection pool.
Unfortunately, I do not know if you can do this directly thru NHibernate, but you can use a SQLConnection object to issue a ClearPool or ClearAllPools call ...
Related
Everytime you use spring JdbcTemplate, does it actually create a new connection to the sql server ?
Answer 1:
In short yes it does close the connection. The long answer it depends.
When you don’t have a Spring managed transaction then yes the JdbcTemplate will call the close() method on the Connection. However if there was already a connection available due to Springs transaction management closing the connection will be handled by Springs transaction support, which in turn also will call close() on the Connection.
The only difference is when the connection is closed but close() will be called.
If the connection will be actually closed depends on which DataSource is used, in general when using a connection pool the connection will be returned to the pool instead of actually closing the connection.
Answer 2:
Yes it does.
And if the connection was obtained from connection pool, it won’t actually close the connection, rather will send it back to the pool.
Answer 3:
No need to close the connection manually. Spring container itself to take of the operation. Kindly refer this spring url,
http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/jdbc.html
Answer 4:
We can also close connection while using jdbcTemplete, in some cases it compulsory to close connection after execute query otherwise getting connection issue. for more details visit
[Close connection in jdbc template][1] [1]: http://www.javaiq.in/2019/05/jdbctemplate.html
Link is: https://inneka.com/programming/spring/does-springs-jdbctemplate-close-the-connection-after-query-timeout/
Understanding datasource interface is the key to understanding the answer to this question. JdbcTemplate has a dependency on datasource and official javadoc for DataSource interface says:
Datasource is a factory for connections to the physical data source that this datasource object represents.
It means every-time a JdbcTemplate is used for executing a SQL query, it requests a connection from the datasource. Datasource retrieves a connection from the connection pool, if available, and gives it to JdbcTemplate. JdbcTemplate then executes the SQL query and releases the connection back to the pool.
So, yes, we would need a new connection every-time JdbcTemplate is used for executing a SQL query but that connection is always fetched from the connection pool that any implementation of Datasource interface maintains.
Maintaining a connection pool is lot more time efficient than creating a new connection on demand. Obviously, considering memory limits, there has to be an upper cap on the connection pool size.
A long-running application uses the MS C OBDC API to create and use SQL connections to an Oracle DB. The application was originally designed to establish an ODBC connection at startup and keep that connection indefinitely as the application runs, potentially for weeks or months.
We're seeing very infrequent cases where a connection suddenly dies and I wondered if that's because we're using them wrong, or if it's considered OK to hold a connection like this. Can anyone point me to some definitive information on the subject?
I'm not sure there's definitive information regarding this, but with long-running programs you always have to be prepared for this kind of incidents, they just happen (and not only with db connections but also with sockets that remain open for extended periods). I have no experience with Oracle, but I have a very similar setup with Informix, and this is (in pseudocode) what we do
while (programissupposedtorun) {
opendb();
do {
youractivities();
} while(dbisok);
closedbandcleanup();
}
As long as you are able to correctly detect that the connection died and are able to resume processing without losing data you should be OK.
I'm not familiar with ODBC but such use cases are best handled with a connection pool. Your application can simply request a connection from the pool when it has some work and release it as soon as its done -- the pool will take care of actually (re)connecting to the database.
A quick search for ODBC connection pooling brought this up: Driver Manager Connection Pooling
I have a project that connects to many SQL Server databases. They all have the same schema, but different data. Data is essentially separated by customer. When a request comes in to the asp.net app, it can tell which database is needed and sets up a session.
What we're doing now is creating a new SessionFactory for each customer database. This has worked out alright for a while, but with more customers we're creating more databases. We're starting to run into memory issues because each factory has it's own QueryPlanCache. I wrote a post about my debugging of the memory.
I want to make it so that we have one SessionFactory that uses a ConnectionProvider to open a connection to the right database. What I have so far looks something like this:
public class DatabaseSpecificConnectionProvider : DriverConnectionProvider
{
public override IDbConnection GetConnection()
{
if (!ThreadConnectionString.HasValue)
return base.GetConnection();
var connection = Driver.CreateConnection();
try
{
connection.ConnectionString = ThreadConnectionString.Value;
connection.Open();
}
catch(DbException)
{
connection.Dispose();
throw;
}
return connection;
}
}
This works great if there is only one database needed to handle the request since I can set the connection string in a thread local variable during initization. Where I run into trouble is when I have an admin-level operation that needs to access several databases.
Since the ConnectionProvider has no idea which session is opening the connection, it can't decide which one to use. I could set a thread local variable before opening the session, but that has trouble since the session connections are opened lazily.
I'm also going to need to create a CacheProvider to avoid cache colisions. That's going to have run into a similar problem.
So any ideas? Or is this just asking too much from NHibernate?
Edit: I found this answer that suggests I'd have to rely on some global state which is what I'd like to avoid. If I have multiple sessions active, I'd like the ConnectionProvider to respond with a connection to the appropriate database.
Edit 2: I'm leaning towards a solution that would create a ConnectionProvider for the default Session that is always used for each site. And then for connections to additional databases I'd open the connection and pass it in. The downsides to this I can see is that I can't use the second level cache on ancillary Sessions and I'll have to track and close the connection myself.
I've settled on a workaround and I'm listing it here in case anyone runs across this again.
It turned out I couldn't find anyway to make the ConnectionProvider change databases depending on session. It could only realistically depend on the context of the current request.
In my case, 95% of the time only the one customer's database is going to be needed. I created a SessionFactory and a ConnectionProvider that would handle that. For the remaining corner cases, I created a second SessionFactory and when I open the Session, I pass in a new Connection.
The downside to that is that the Session that talks to the second database can't use the second level cache and I have to make sure I close the connection at the end of the request.
That seems to be working well enough for now, but I'm curious how well it'll stand up in the long run.
I am considering using Fluent NHibernate for a new application with SQL Server 2008 and I am having trouble understanding the connection handling behavior I am seeing.
I am monitoring connections using sp_who2 and here is what I see:
When the SessionFactory is created, a single connection is opened. This connection
seems to stay open until the app is killed.
No connection is opened when a new session is opened. (That's ok, I understand NHibernate waits until the last moment to create database connections).
No new connection is opened even when I run a query through NHibernate. I must assume it is using the connection created when the SessionFactory was created, which is still open. I set a breakpoint after the query (before the session was closed), and no new sessions had appeared in sp_who.
Running an entire app through a single connection is not acceptable (obviously). How can I ensure each ISession gets its own connection? I'm sure there's something obvious I'm missing here...
Thanks in advance.
The behaviour that you see is nothing NHibernate specific - Connection pooling is default behaviour in SQL Server.
Even if it may sound awkward at first glance, it actually is a good thing because creating new connections and maintaining them is expensive.
(for more information, see the Wikipedia article about connection pooling)
So there is no need to try to get NH to open a new connection for each session, because reusing existing connections actually improves SQL Server performance.
I have NHibernate configured with Fluent NNibernate connecting to a PostgreSQL database.
I have a worker class that takes an ISessionFactory as a constructor parameter and consumes messages from a queue. For each message the worker process calls ISessionFactory.OpenSession() and it does some database processing.
When I add more worker processes the performance of the system remains the same which is odd.
After some more investigation I realized that all worker processes are using a single database connection. For example I would add 8 worker processes but on the database I can see only one database connection.
My understanding is that ISessionFactory.OpenSession() will open a new database connection unless the Connection Pool is full.
So is my understanding wrong or is this and issue with the Postgres NHibernate driver.
OpenSession does not open a database connection until needed, and it closes it (i.e. releases it back into the pool) as soon as possible.
By default the session will keep the connection open for the life time of a transaction and as Diego said, it only opens it when needed.
If you want to manage your own connections you can call
ISessionFactory.OpenSession(myConnection);