`

Hibernate的flush()和evict()总结

阅读更多
关键字: 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顺序提交相关操作
Java代码
/**   
     * 测试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);     
        }     
    }   

/** 
     * 测试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

    ### 关于flush和evict在Hibernate中的应用 #### 一、引言 在持久层框架Hibernate中,`flush()`和`evict()`方法是开发者在处理数据时经常会遇到的两个重要概念。它们对于理解Hibernate的工作机制及其缓存管理至关...

    hibernate的flush机制

    然而,对于Hibernate的一些高级特性,如Flush机制,深入理解其工作原理对于避免潜在的陷阱和提高应用程序性能至关重要。 #### Flush机制概览 在Hibernate中,Flush机制是用于同步Session缓存与数据库之间变化的...

    hibernate中evict()和clear()的区别.docx

    总的来说,`evict()`和`clear()`都是用于管理Hibernate Session缓存的方法,但它们处理的对象范围和时机不同。理解这两个方法的差异,可以帮助我们更有效地控制对象的状态,避免潜在的运行时异常,并提高应用程序的...

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

    在Hibernate框架中,Session是与数据库交互的主要接口,它提供了多种方法来操作对象的状态和数据。本文主要讨论了`get`、`load`方法以及`flush`、`clear`、`evict`等方法的区别。 首先,让我们关注`get`和`load`的...

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

    在使用Hibernate进行数据库操作时,事务管理和`flush`方法的正确使用至关重要,因为它们直接影响到数据的一致性和安全性。在本文中,我们将深入探讨Hibernate的事务处理机制以及`flush`方法的用法,并分析为何在某些...

    在Hibernate中处理批量更新和批量删除

    在IT领域,尤其是在Java...通过使用`flush()`和`evict()`、执行原生SQL语句或使用存储过程,可以显著提升数据库操作的效率,同时减少服务器资源的消耗。开发者应根据具体的应用场景和数据库特性选择最合适的优化方案。

    西安领航核心项目Hibernate部分重点、难点总结

    西安领航核心项目的Hibernate部分,涉及了许多重要的概念和操作,其中包含了对象状态管理、方法区别、执行顺序以及关联关系处理等关键知识点。以下是对给定文件中提到的关键知识点的详细解读: ### 持久化对象的三...

    在Hibernate应用中处理批量更新和批量删除

    1. **使用`flush()`和`evict()`方法**:在修改实体后,主动调用`session.flush()`方法,使Hibernate将缓存中的变更同步到数据库,然后调用`session.evict(entity)`方法,从缓存中移除实体,这样下一次操作不会受到...

    hibernate一级缓存

    2. **缓存与数据库的同步**:当我们调用`Session.flush()`方法时,Hibernate会将一级缓存中所有更改过的对象同步到数据库,确保数据的一致性。而在事务提交(`Transaction.commit()`)时,Hibernate会自动执行flush...

    Hibernate code

    综上所述,`Session.flush()`方法在Hibernate中起着至关重要的作用,它不仅能够确保数据的一致性和完整性,还能为开发者提供更多控制程序流的可能性。了解何时以及如何使用`flush()`对于开发高性能的应用程序至关...

    Hibernate 使用缓存时,数据同步问题

    Hibernate提供了两种缓存级别:一级缓存和二级缓存。 - **一级缓存**:存在于Session范围内,用于存储实体的实例和状态。当一个实体被加载到Session时,其状态会保存在一级缓存中,以便后续操作能够快速访问,无需...

    hibernate总结

    3. 可以使用 `Session.evict(obj)` 移除对象,`Session.clear()` 清空所有对象,或关闭 `Session`。 **对象状态** 1. **临时态(瞬态)**:新创建的对象,未与 Session 关联,数据库中无记录。 2. **持久态**:...

    jsp Hibernate批量更新和批量删除处理代码.docx

    总结来说,批量更新和批量删除是提升Hibernate应用性能的关键技巧。通过合理利用`flush()`、`evict()`以及直接使用JDBC执行SQL,可以有效地处理大数据量的更新和删除操作,降低内存占用并减少对数据库的访问次数。在...

    Hibernate三种状态区分

    理解 Hibernate 的对象状态和这些操作方法的差异对于优化数据库操作和确保数据一致性至关重要。正确地使用这些状态和方法可以避免数据丢失,提高应用程序的性能和可靠性。在实际开发中,根据业务需求选择合适的方法...

    Hibernate的缓存机制.docx

    用户无法直接操作一级缓存内容,但可以通过flush()、evict()和clear()方法间接管理。flush()用于使缓存与数据库同步,evict()用于清除指定对象,而clear()则清空所有对象。 二级缓存是基于应用程序级别的,作用在...

    Hibernate中的实体状态及转换

    在Java的ORM框架Hibernate中,实体管理是其...理解并熟练运用Hibernate的实体状态转换,对于优化数据操作和提高代码效率至关重要。在实际开发中,开发者应根据业务需求选择合适的转换方式,确保数据的正确性和一致性。

    Hibernate API

    总的来说,Hibernate API 提供了一系列丰富的接口和方法,用于管理数据库操作,包括对象的持久化、查询、事务处理以及缓存管理等。熟练掌握这些API,可以帮助开发者高效、便捷地进行数据库操作,提高代码的可维护性...

    Hibernatehibernate一级缓存.pdf

    在Java的持久化框架Hibernate中,一...总结起来,Hibernate的一级缓存是一个关键特性,它提高了数据访问的效率并降低了数据库的负载。正确理解和使用一级缓存,以及学会管理缓存,是优化Hibernate应用性能的关键步骤。

    Hibernate中对象的三种状态

    本篇将详细阐述Hibernate中的瞬时态、持久态和脱管态,以及它们之间的转换。 1. 瞬时态(Transient): 瞬时态的对象是在内存中创建的,尚未与数据库中的任何记录关联。它们没有持久化标识(ID),在Hibernate的...

Global site tag (gtag.js) - Google Analytics