【问题标题】:Why do i need to add transaction in this?为什么我需要在其中添加交易?
【发布时间】:2014-05-14 11:33:21
【问题描述】:

为什么我们总是需要在休眠中启动事务来保存、插入、删除或更新?

hibernate的自动提交功能默认为false吗?

喜欢这个

public static void main(String[] args) {
        System.out.println("creating empopbjects");
        emp e1=new emp("a","x",1234);
        emp e2=new emp("b","y",324);
        emp e3=new emp("c","z",23345);
        System.out.println("saving emp objects..");
        Session s=myfactory.getsession();
        s.save(e1);
        s.save(e2);
        s.save(e3);
        s.close();
        System.out.println("successfully saved");
    }

这不会保存任何东西,而如果我添加 Transaction 则只会添加它?为什么会这样?

public static void main(String[] args) {
        System.out.println("creating empopbjects");
        emp e1=new emp("a","x",1234);
        emp e2=new emp("b","y",324);
        emp e3=new emp("c","z",23345);
        System.out.println("saving emp objects..");
        Session s=myfactory.getsession();
        Transaction t =s.beginTransaction();
        s.save(e1);
        s.save(e2);
        s.save(e3);
        t.commit();
        s.close();
        System.out.println("successfully saved");
    }

【问题讨论】:

    标签: java hibernate jpa orm transactions


    【解决方案1】:

    one of the SO page 对您的问题的明确回答在这里。

    看下面的代码, 无需访问数据库 交易边界:

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

    默认情况下,在 Java SE 环境中 使用 JDBC 配置,这是 如果你执行这个会发生什么 sn-p:

    1. 新会话已打开。此时未获取数据库连接 点。
    2. 调用 get() 触发 SQL SELECT。 Session 现在获得了一个 JDBC 来自连接池的连接。 休眠,默认情况下,立即 在此关闭自动提交模式 与 setAutoCommit(false) 的连接。 这有效地启动了 JDBC 交易!
    3. SELECT 在此 JDBC 事务中执行。会议是 关闭,并返回连接 到池中并由 Hibernate 释放 — Hibernate 在 JDBC 上调用 close() 联系。会发生什么 未提交的交易?

    这个问题的答案是,“它 要看!” JDBC 规范 没有说任何关于待处理的事情 调用 close() 时的事务 一个连接。会发生什么取决于 供应商如何实施 规格。使用 Oracle JDBC 驱动程序,例如,调用 close() 提交事务!最多 其他 JDBC 供应商采取理智的方式 并回滚任何待处理的事务 当 JDBC Connection 对象是 关闭并且资源返回到 游泳池。

    显然,这不会成为问题 你已经执行的 SELECT,但是看 在这种变化:

    Session session = getSessionFactory().openSession(); 
    Long generatedId = session.save(item); 
    session.close(); 
    

    此代码会导致 INSERT 语句,在一个内部执行 从未提交的事务或 回滚。在 Oracle 上,这块 代码永久插入数据;在 其他数据库,可能不会。 (这个 情况略多 复杂:执行 INSERT 仅当标识符生成器 需要它。例如,一个 标识符值可以从 没有 INSERT 的序列。 该 然后持久实体排队,直到 刷新时插入——从不 发生在这段代码中。一个身份 策略需要立即插入 为要生成的值。)

    底线:使用明确的事务划分。

    【讨论】:

      【解决方案2】:

      Hibernate Session 是一个Unit of Work,查询只在刷新期间执行(这可能发生在执行任何查询之前,或者当您当前正在执行的事务被提交时)。

      自动提交仅在 SQL 控制台中有意义,在企业应用程序中是不可取的。使用 ORM 工具时,您管理的是实体对象状态转换,而不是执行 DML 操作。只有在刷新时,状态转换才会转换为 DML 操作。

      因此,虽然您可以在自动提交中编写 JDBC 语句,但 JPA 不允许您这样做。

      【讨论】:

        猜你喜欢
        • 2022-01-18
        • 1970-01-01
        • 2020-08-22
        • 1970-01-01
        • 2020-03-20
        • 2016-12-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多