Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does beginTransaction in Hibernate allocate a new DB connection?

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

like image 495
illscience Avatar asked Mar 29 '10 18:03

illscience


2 Answers

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.

like image 57
Pascal Thivent Avatar answered Oct 18 '22 16:10

Pascal Thivent


(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.)

like image 24
Bozho Avatar answered Oct 18 '22 18:10

Bozho