views:

280

answers:

2

Hi folks - Just wondering if beginning a new transaction in Hibernate actually allocates a connection to the DB?

I'm concerned b/c our server begins a new transaction for each request received, even if that request doesn't interact with the DB. We're seeing DB connections as a major bottleneck, so I'm wondering if I should take the time narrow the scope of my transactions.

Searched everywhere and haven't been able to find a good answer. The very simple code is here:

    SessionFactory sessionFactory = (SessionFactory) Context.getContext().getBean("sessionFactory");
    sessionFactory.getCurrentSession().beginTransaction();
    sessionFactory.getCurrentSession().setFlushMode(FlushMode.AUTO);

thanks very much! a

+4  A: 

(Updated per Pascal Thivent's comment)

Each Session creates a database connection if there is a need for that - e.g. if a transaction is started. The connection is not opened with the mere creation of the session.

To overcome this, you can use a connecetion pool so that connections are reused. Or you can make sure (as it appears you did) that no transaction is started automatically.

(This discusses read-only transactions. Take a look.)

Bozho
Thanks, we are using a connection pool already. By not beginning a transaction by default we were able to massively reduce the load on our database.
illscience
Actually, the connection is lazy-loaded in a `Session`. See my answer for details.
Pascal Thivent
@Pascal Thivent hm, interesting, and logical :)@illscience please change the accepted answer
Bozho
@Bozho +1 for the fix
Pascal Thivent
+1  A: 

According to the section 11.1. Session and transaction scopes of the Hibernate documentation:

A SessionFactory is an expensive-to-create, threadsafe object, intended to be shared by all application threads. It is created once, usually on application startup, from a Configuration instance.

A Session is an inexpensive, non-threadsafe object that should be used once and then discarded for: a single request, a conversation or a single unit of work. A Session will not obtain a JDBC Connection, or a Datasource, unless it is needed. It will not consume any resources until used.

In order to reduce lock contention in the database, a database transaction has to be as short as possible. Long database transactions will prevent your application from scaling to a highly concurrent load. It is not recommended that you hold a database transaction open during user think time until the unit of work is complete.

Now, to answer your question:

  • getting a Session does not immediately acquire a connection (the connection is lazy loaded)
  • but calling beginTransaction() will cause the load of the connection for the given Session
  • subsequent calls will reuse the same connection

Look at org.hibernate.impl.SessionImpl#beginTransaction() and go through the code for more details.

Pascal Thivent
+1, of course (15chrs)
Bozho
@Bozho Thanks !
Pascal Thivent