简体   繁体   English

Hibernate Java中的会话和事务

[英]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 在Java Hibernate中,当我们需要对DB做一些事情时,我们需要:1。打开会话2.开始事务3.完成事务4.关闭会话

  • 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()? 为什么getStudentList()中没有事务? Thank in advance 预先感谢

This hibernate article explains the behavior of SELECT operations which are not explicitly executed within a transaction. 这篇hibernate 文章解释了未在事务中显式执行的SELECT操作的行为。

The following example is given in the article but it's also true for your query example. 本文给出了以下示例,但对于您的查询示例也是如此。

Session session = sessionFactory.openSession(); 会话会话= sessionFactory.openSession();
session.get(Item.class, 123l); session.get(Item.class,123l);
session.close(); 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. 对get()的调用会触发SQL SELECT。 The Session now obtains a JDBC Connection from the connection pool. Session现在从连接池获取JDBC连接。 Hibernate, by default, immediately turns off the autocommit mode on this connection with setAutoCommit(false). 默认情况下,Hibernate会立即使用setAutoCommit(false)关闭此连接上的自动提交模式。 This effectively starts a JDBC transaction! 这有效地启动了JDBC事务!
  3. The SELECT is executed inside this JDBC transaction. SELECT在此JDBC事务中执行。 The Session is closed, and the connection is returned to the pool and released by Hibernate — Hibernate calls close() on the JDBC Connection. 会话关闭,连接返回到池并由Hibernate释放 - Hibernate在JDBC Connection上调用close()。 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. 这个问题的答案是,“它取决于!”在连接上调用close()时,JDBC规范没有说明挂起事务的任何内容。 What happens depends on how the vendors implement the specification. 发生的情况取决于供应商如何实施规范。 With Oracle JDBC drivers, for example, the call to close() commits the transaction! 例如,使用Oracle JDBC驱动程序,对close()的调用将提交事务! 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. 当JDBC Connection对象关闭并且资源返回到池时,大多数其他JDBC供应商采用相同的路由并回滚任何挂起的事务。 Obviously, this won't be a problem for the SELECT [...] 显然,对于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. 现在,如果Item的新价格是否持久,它依赖于JDBC驱动程序。

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. 因此,只要没有数据库更改,即使JDBC驱动程序将回滚事务,您也可以忽略纯SELECT操作的开始和提交事务。

But anyway I would strongly recommend using transactions on any operation to avoid misunderstanding and problems. 但无论如何,我强烈建议在任何操作上使用交易以避免误解和问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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