java - Hibernate Java 中的 session 和事务

标签 java hibernate session transactions

在 Java Hibernate 中,当我们需要对 DB 执行某些操作时,我们需要: 1. 公开 session 2. 开始交易 3. 完成交易 4.关闭 session

  • 例如,如果我想获取学生列表:

    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;
    }
    
  • 插入学生

    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;
    } 
    

为什么 getStudentList() 中没有事务?提前致谢

最佳答案

这个 hibernate article解释了事务中未显式执行的 SELECT 操作的行为。

文章中给出了以下示例,但它也适用于您的查询示例。

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 sane 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 [...]

让我们扩展上面的示例来引发可能的问题。

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

现在,Item 的新价格是否保留取决于 JDBC 驱动程序。

因此,您可以忽略纯 SELECT 操作上的开始和提交事务,即使您的 JDBC 驱动程序将回滚事务(只要您没有数据库更改)。

但无论如何,我强烈建议在任何操作中使用事务以避免误解和问题。

关于java - Hibernate Java 中的 session 和事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38878550/

相关文章:

java - 阻止 Eclipse 缩进使用 Ctrl-/创建的注释

java - 无法删除 spring-hibernate 中的实体

javascript - 当 session 结束时执行 sails.js 中的代码

database - 使用连接池或 session 管理数据库连接。如何?

asp.net-mvc - HttpWebRequest - ASP .NET MVC 3 传递 session 状态

java - SCJP 测试 Killer 310-065 (Java)

java - 如何使用 IJavaProject#findType() 获取java项目中的所有方法?

java - 在 java 中播放 "*.mp3"文件的最佳方式是什么?

java - Hibernate 误读

java - Hibernate JPA无法在SQL Server中创建索引