`

Hibernate的flush()和evict()

阅读更多
隔离级别  脏读 不可重复读 幻读

ReadUncommitted  Y Y Y
ReadCommitted N Y Y
RepeatableRead N N Y
Serializable N N N

ReadCommited是oracle的默认隔离级别。可以通过悲观锁,消除不可重复读。
RepeatableRead是Mysql的默认级别。


session flush方法主要做了两件事:
* 清理缓存
* 执行sql

session在什么情况下执行flush
* 默认在事务提交时
* 显示的调用flush
* 在执行查询前,如:iterate

hibernate按照save(insert),update、delete顺序提交相关操作
/**  
     * 测试uuid主键生成策略  
     */  
    public void testSave1() {   
        Session session = null;   
        Transaction tx = null;   
        try {   
            session = HibernateUtils.getSession();   
            tx = session.beginTransaction();   
  
            User1 user = new User1();   
            user.setName("李四");   
            user.setPassword("123");   
            user.setCreateTime(new Date());   
            user.setExpireTime(new Date());   
               
            //因为user的主键生成侧路采用的是uuid,所以调用完成save后,只是将user纳入到了session的管理   
            //不会发出insert语句,但是id已经生成,session中existsInDatebase状态为false   
            session.save(user);   
               
            //调用flush,hibernate会清理缓存,执行sql   
            //如果数据库的隔离级别设置为为提交读,那么我们可以看到flush过的数据   
            //并且session中existsInDatebase状态为true   
            session.flush();   
               
            //提交事务   
            //默认情况下commit操作会先执行flush清理缓存,所以不用显示的调用flush   
            //commit后数据是无法回滚的   
            tx.commit();   
        }catch(Exception e) {   
            e.printStackTrace();   
            tx.rollback();   
        }finally {   
            HibernateUtils.closeSession(session);   
        }   
    }   
       
    /**  
     * 测试native主键生成策略  
     */  
    public void testSave2() {   
        Session session = null;   
        Transaction tx = null;   
        try {   
            session = HibernateUtils.getSession();   
            tx = session.beginTransaction();   
  
            User2 user = new User2();   
            user.setName("张三1");   
            user.setPassword("123");   
            user.setCreateTime(new Date());   
            user.setExpireTime(new Date());   
               
            //因为user的主键生成策略为native,所以调用session.save后,将执行insert语句,返回有数据库生成的id   
            //纳入了session的管理,修改了session中existsInDatebase状态为true   
            //如果数据库的隔离级别设置为为提交读,那么我们可以看到save过的数据   
            session.save(user);   
            tx.commit();   
        }catch(Exception e) {   
            e.printStackTrace();   
            tx.rollback();   
        }finally {   
            HibernateUtils.closeSession(session);   
        }   
    }   
       
       
    /**  
     * 测试uuid主键生成策略  
     */  
    public void testSave3() {   
        Session session = null;   
        Transaction tx = null;   
        try {   
            session = HibernateUtils.getSession();   
            tx = session.beginTransaction();   
  
            User1 user = new User1();   
            user.setName("王五");   
            user.setPassword("123");   
            user.setCreateTime(new Date());   
            user.setExpireTime(new Date());   
               
            //因为user的主键生成侧路采用的是uuid,所以调用完成save后,只是将user纳入到了session的管理   
            //不会发出insert语句,但是id已经生成,session中existsInDatebase状态为false   
            session.save(user);   
               
            //将user对象从session中逐出,即session的EntityEntries属性中逐出   
            session.evict(user);   
               
            //无法成功提交,因为hibernate在清理缓存时,在session的insertions集合中取出user对象进行insert操作后   
            //需要更新entityEntries属性中的existsInDatabase为true,而我们采用evict已经将user从session的entityEntries   
            //中逐出了,所以找不到相关数据,无法更新,抛出异常   
            tx.commit();   
        }catch(Exception e) {   
            e.printStackTrace();   
            tx.rollback();   
        }finally {   
            HibernateUtils.closeSession(session);   
        }   
    }   
       
    /**  
     * 测试uuid主键生成策略  
     */  
    public void testSave4() {   
        Session session = null;   
        Transaction tx = null;   
        try {   
            session = HibernateUtils.getSession();   
            tx = session.beginTransaction();   
  
            User1 user = new User1();   
            user.setName("王五");   
            user.setPassword("123");   
            user.setCreateTime(new Date());   
            user.setExpireTime(new Date());   
               
            //因为user的主键生成侧路采用的是uuid,所以调用完成save后,只是将user纳入到了session的管理   
            //不会发出insert语句,但是id已经生成,session中existsInDatebase状态为false   
            session.save(user);   
               
            //flush后hibernate会清理缓存,会将user对象保存到数据库中,将session中的insertions中的user对象   
            //清除,并且设置session中existsInDatebase的状态为true   
            session.flush();   
               
            //将user对象从session中逐出,即session的EntityEntries属性中逐出   
            session.evict(user);   
               
            //可以成功提交,因为hibernate在清理缓存时,在session的insertions集合中无法找到user对象   
            //所以就不会发出insert语句,也不会更新session中的existsInDatabase的状态   
            tx.commit();   
        }catch(Exception e) {   
            e.printStackTrace();   
            tx.rollback();   
        }finally {   
            HibernateUtils.closeSession(session);   
        }   
    }   
       
    /**  
     * 测试native主键生成策略  
     */  
    public void testSave5() {   
        Session session = null;   
        Transaction tx = null;   
        try {   
            session = HibernateUtils.getSession();   
            tx = session.beginTransaction();   
  
            User2 user = new User2();   
            user.setName("张三11");   
            user.setPassword("123");   
            user.setCreateTime(new Date());   
            user.setExpireTime(new Date());   
               
            //因为user的主键生成策略为native,所以调用session.save后,将执行insert语句,返回有数据库生成的id   
            //纳入了session的管理,修改了session中existsInDatebase状态为true   
            //如果数据库的隔离级别设置为为提交读,那么我们可以看到save过的数据   
            session.save(user);   
               
            //将user对象从session中逐出,即session的EntityEntries属性中逐出   
            session.evict(user);   
               
            //可以成功提交,因为hibernate在清理缓存时,在session的insertions集合中无法找到user对象   
            //所以就不会发出insert语句,也不会更新session中的existsInDatabase的状态   
            tx.commit();   
        }catch(Exception e) {   
            e.printStackTrace();   
            tx.rollback();   
        }finally {   
            HibernateUtils.closeSession(session);   
        }   
    }   
       
    /**  
     * 测试assigned主键生成策略  
     *   
     */  
    public void testSave6() {   
        Session session = null;   
        Transaction tx = null;   
        try {   
            session = HibernateUtils.getSession();   
            tx = session.beginTransaction();   
  
            User3 user = new User3();   
            user.setId("001");   
            user.setName("张三");   
               
            session.save(user);   
               
            user.setName("王五");   
            session.update(user);   
               
            User3 user3 = new User3();   
            user3.setId("002");   
            user3.setName("李四");   
            session.save(user3);   
               
            //Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)   
            //Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)   
            //Hibernate: update t_user3 set name=?, password=?, create_time=?, expire_time=? where user_id=?   
            //hibernate按照save(insert),update、delete顺序提交相关操作   
            tx.commit();   
        }catch(Exception e) {   
            e.printStackTrace();   
            tx.rollback();   
        }finally {   
            HibernateUtils.closeSession(session);   
        }   
    }      
       
    /**  
     * 测试assigned主键生成策略  
     *   
     */  
    public void testSave7() {   
        Session session = null;   
        Transaction tx = null;   
        try {   
            session = HibernateUtils.getSession();   
            tx = session.beginTransaction();   
  
            User3 user = new User3();   
            user.setId("003");   
            user.setName("张三");   
               
            session.save(user);   
               
            user.setName("王五");   
            session.update(user);   
               
            session.flush();   
               
            User3 user3 = new User3();   
            user3.setId("004");   
            user3.setName("李四");   
            session.save(user3);   
               
            //Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)   
            //Hibernate: update t_user3 set name=?, password=?, create_time=?, expire_time=? where user_id=?   
            //Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)   
            //因为我们在session.udpate(user)后执行了flush,所以在清理缓存时执行flush前的sql不会生成   
            //sql会按照我们的意愿执行   
            tx.commit();   
        }catch(Exception e) {   
            e.printStackTrace();   
            tx.rollback();   
        }finally {   
            HibernateUtils.closeSession(session);   
        }   
    }  



Hibernate的flush机制:http://sind.iteye.com/blog/255429
分享到:
评论

相关推荐

    关于flush和evict

    主要讲解hibernate中flush()和evict()的用处

    hibernate的flush机制

    对hibernate的flush机制有兴趣可以看看

    hibernate_flush 深入了解

    NULL 博文链接:https://wuhaidong.iteye.com/blog/766562

    hibernate的session.flush

    博文链接:https://llying.iteye.com/blog/221702

    Hibernate中get和load方法的区别以及close(),clear()、evict()等的区别

    Hibernate Session中的 flush方法的作用 get和load方式是根据id取得一个记录 下边详细说一下get和load的不同,因为有些时候为了对比也会把find加进来。 1.从返回结果上对比: load方式检索不到的话会抛出org....

    深入理解Hibernate中的flush机制

    主要介绍了深入理解Hibernate中的flush机制,本文是对flush机制深入研究得出的一些结论总结,需要的朋友可以参考下

    Hibernate的事务处理机制和flush方法的用法.docx

    关于在使用 hibernate 在提交事务时常遇到的异常: ...其实这个异常一般都是和我们在操作session flush方法和提交事务过程中会抛出的,下面就具体结合session的事务和声明周期来具体分析下,为什么会有这样的异常;

    Hibernate的Session_flush与隔离级别代码详解

    主要介绍了Hibernate的Session_flush与隔离级别代码详解,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下

    hibernate的flush()、refresh()、clear()针对一级缓存的操作的区别.docx

    session.flush()和session.clear()就针对session的一级缓存的处理。 简单的说, 1 session.flush()的作用就是将session的缓存中的数据与数据库同步。 2 session.clear()的作用就是清除session中的缓存数据(不管缓存...

    hibernate基础教程

    3、批量存储:session.flush()和session.clear() 二 Hibernate中的二级缓存结构 在Hibernate中使用两极缓存结构,第一级缓存是Session级别的缓存,Session级别的缓存是由Hibernate...

    Hibernate+中文文档

    3.4. Hibernate JDBC和连接(connection)属性 3.5. Hibernate缓存属性 3.6. Hibernate事务属性 3.7. 其他属性 3.8. Hibernate SQL方言 (hibernate.dialect) 3.9. Hibernate日志类别 3.10. JTA ...

    Hibernate学习笔记

    007 Hibernate 基本映射标签和属性介绍 008 多对一 关联映射 009 一对一 主键关联映射_单向 010 一对一 主键关联映射_双向 011 一对一 唯一外键关联映射_单向 012 一对一 唯一外键关联映射_双向 013 session_flush ...

    hibernate操作数据库笔记

    //该方法将到classpath下解析hibernate.cfg.xml中的配置,如果不用Hibernate默认的配置文件名和路径,可在该方法中指定Hibernate配置文件的名称和路径 2.用Configuration对象获取SessionFactory和Session对象:...

    hibernate3.2中文文档(chm格式)

    3.4. Hibernate JDBC和连接(connection)属性 3.5. Hibernate缓存属性 3.6. Hibernate事务属性 3.7. 其他属性 3.8. Hibernate SQL方言 (hibernate.dialect) 3.9. Hibernate日志类别 3.10. JTA ...

    深入理解ob_flush和flush的区别(ob_flush()与flush()使用方法)

    注意:ob_flush()和flush()这两个函数一般要一起使用,顺序是先ob_flush(),然后flush(),它们的作用是刷新缓冲区。这里具体的说下什么时候要用到刷新缓冲区和为什么要刷新缓冲区。 一、什么时候要刷新缓冲区 当...

    HibernateAPI中文版.chm

    3.4. Hibernate JDBC和连接(connection)属性 3.5. Hibernate缓存属性 3.6. Hibernate事务属性 3.7. 其他属性 3.8. Hibernate SQL方言 (hibernate.dialect) 3.9. Hibernate日志类别 3.10. JTA ...

    hibernate学习笔记

    session flush测试(hibernate_session_flush) 12 hihernate一对多关联映射(单向Classes----->Student) 13 hihernate一对多关联映射(双向Classes<----->Student)(常用) 14 hibernate一对多双向自连接关联映射...

    hibernate 教程

    开始Hibernate之旅 1.2. 第一个可持久化类 1.3. 映射cat 1.4. 与猫同乐 1.5. 结语 2. 体系结构 2.1. 总览 2.2. JMX集成 2.3. JCA支持 3. SessionFactory配置 3.1. 可编程配置方式...

    Hibernate使用技巧汇总

    两种配置文件: A.hibernate.cfg.xml 和 B.hibernate.properties A中可含映射文件的配置,而B中hard codes加映射文件。 A。Configuration config=new Configuration().config(); B. ...

    Hibernate 中文 html 帮助文档

    10.10. Session刷出(flush) 10.11. 传播性持久化(transitive persistence) 10.12. 使用元数据 11. 事务和并发 11.1. Session和事务范围(transaction scope) 11.1.1. 操作单元(Unit of work) 11.1.2. 长对话 11.1.3. ...

Global site tag (gtag.js) - Google Analytics