为什么我需要在此添加交易?

时间:2014-05-14 11:33:22

标签: java hibernate jpa orm transactions

为什么我们需要始终在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");
    }

这不会保存任何东西,而如果我添加交易,那么只添加它?为什么呢?

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

2 个答案:

答案 0 :(得分:2)

Hibernate Session是Unit of Work,查询仅在刷新时执行(可能在执行任何查询之前,或者当前正在执行的Transaction已提交时)。

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

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

答案 1 :(得分:2)

来自one of the SO page的问题的明确答案就在这里。

  

查看以下代码,其中   无需访问数据库   交易边界:

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

默认情况下,在Java SE环境中   使用JDBC配置,这是   如果执行此操作会发生什么   片段:

     
      
  1. 打开一个新会话。它没有获得数据库连接   点。
  2.   
  3. 对get()的调用会触发SQL SELECT。 Session现在获得了JDBC   从连接池连接。   默认情况下,Hibernate立即执行   在此关闭自动提交模式   与setAutoCommit的连接(false)。   这有效地启动了JDBC   交易!
  4.   
  5. SELECT在此JDBC事务中执行。会议是   关闭,并返回连接   到游泳池并由Hibernate发布    - Hibernate在JDBC上调用close()   连接。怎么了?   未提交的交易?
  6.         

    这个问题的答案是,“它   取决于!“JDBC规范   对待处理没有说什么   调用close()时的事务   一个连接。会发生什么取决于   供应商如何实施   规格。使用Oracle JDBC   司机,例如,打电话给   close()提交事务!最   其他JDBC供应商采取理智的路线   并回滚任何待处理的交易   当JDBC Connection对象是   关闭,资源返回   游泳池。

         

    显然,这不会是一个问题   你执行的SELECT,但看   在这种变化:

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

    此代码导致INSERT   声明,在一个内部执行   从未提交的事务或   回滚。在Oracle上,这篇文章   代码永久插入数据;在   其他数据库,它可能不会。 (这个   情况略多一些   复杂:执行INSERT   只有标识符生成器   需要它。例如,一个   标识符值可以从中获得   没有INSERT的序列。的的   然后将持久实体排队直到   冲洗时间插入 - 永远不会   发生在此代码中。身份   策略需要立即INSERT   要生成的值。)

底线:使用显式事务划分。