简体   繁体   中英

Session and Transaction in Hibernate Java

In Java Hibernate, when we need to do something with DB we need: 1. Open session 2. Begin transaction 3. Finish transaction 4. Close session

  • For example if I want to get Student list:

     public static List<Student> getStudentList() { List<Student> l = null; Session session = HibernateUtil.getSessionFactory().openSession(); try { String hql = "from Student"; Query query = session.createQuery(hql); l = query.list(); } catch (HibernateException ex) { //Log the exception System.err.println(ex); } finally { session.close(); } return l; } 
  • Insert a student

     public static boolean addStudent(Student s) { Session session = HibernateUtil.getSessionFactory().openSession(); if (... /* check if student is already exists*/) { return false; } Transaction transaction = null; try { transaction = session.beginTransaction(); session.save(s); transaction.commit(); } catch (HibernateException ex) { //Log the exception transaction.rollback(); System.err.println(ex); } finally { session.close(); } return true; } 

Why there is no transaction in getStudentList()? Thank in advance

This hibernate article explains the behavior of SELECT operations which are not explicitly executed within a transaction.

The following example is given in the article but it's also true for your query example.

Session session = sessionFactory.openSession();
session.get(Item.class, 123l);
session.close();

  1. A new Session is opened. It doesn't obtain a database connection at this point.
  2. The call to get() triggers an SQL SELECT. The Session now obtains a JDBC Connection from the connection pool. Hibernate, by default, immediately turns off the autocommit mode on this connection with setAutoCommit(false). This effectively starts a JDBC transaction!
  3. The SELECT is executed inside this JDBC transaction. The Session is closed, and the connection is returned to the pool and released by Hibernate — Hibernate calls close() on the JDBC Connection. What happens to the uncommitted transaction?

The answer to that question is, “It depends!” The JDBC specification doesn't say anything about pending transactions when close() is called on a connection. What happens depends on how the vendors implement the specification. With Oracle JDBC drivers, for example, the call to close() commits the transaction! Most other JDBC vendors take the same route and roll back any pending transaction when the JDBC Connection object is closed and the resource is returned to the pool. Obviously, this won't be a problem for the SELECT [...]

Lets extend the above example to provoke a possible problem.

Session session = sessionFactory.openSession();
Item item = session.get(Item.class, 123l);
item.setPrice(10);
session.close();

Now it depends on the JDBC driver if the new price for the Item is persisted or not.

So you can neglect begin and commit transactions on pure SELECT operations even when your JDBC driver will rollback the transaction as long as you have no database changes.

But anyway I would strongly recommend using transactions on any operation to avoid misunderstanding and problems.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM