`

hibernate脏数据检查(转)

阅读更多
脏数据检查:
   什么是脏数据?脏数据并不是废弃 和无用的数据,而是状态前后发生变化的数据。我们看下面的代码:
Transaction tx=session.beginTransaction();
User user=(User)session.load(User.class,”1”);//从数据库中加载符合条件的数据
user.setName(“zx”);//改变了user对象的姓名属性,此时user对象成为了所谓的“脏数据”
tx.commit();
当事务提交时,Hibernate会对session中的PO(持久化对象)进行检测,判断持久化对象的状态是否发生了改变,如果发生了改变就会将改变更新到数据库中。这里就存 在一个问题,Hibernate如何来判断一个实体对象的状态前后是否发生了变化。也就是说Hibernate是如何检查出一个数据已经变脏了。

通常 脏数据的检查有如下两种办法:

A、数据对象监控:
数据对象监控是通过拦截器对数据对象的setter方法进行监控来实现的,这类似于数据库中的触发器的概念,当某一个对象的属性调用了setter方法而发生了改变,这时拦截器会捕获这个动作,并且将改属性标志为已经改变,在之后的数据库操作时将 其更新到数据库中。这个方法的优点是提高了数据更新的同步性,但是这也是它的缺点,如果一个实体对象有很多属性发生了改变,势必造成大量拦截器回调方法的 调用,这些拦截器都是通过Dynamic Proxy或者CGLIB实现的,在执行时都会付出一定的执行代价,所以有可能造成更新操作的较大延时。
 
B、数据版本比对:
这 种方法是在持久化框架中保存数据对象的最近读取版本,当提交数据时将提交的数据与这个保存的版本进行比对,如果发现发生了变化则将其同步跟新到数据库中。 这种方法降低了同步更新的实时性,但是当一个数据对象的很多属性发生改变时,由于持久层框架缓存的存在,比对版本时可以充分利用缓存,这反而减少了更新数 据的延迟。

在Hibernate中是采用数据版本比对的方法来进行脏数据检查的,我们结合下面的代码来讲解Hibernate的具体实现策略。
Transaction tx=session.beginTransaction();
User user=(User)session.load(User.class,”1”);
user.setName(“zx”);
tx.commit();

当 调用tx.commit();时好戏就此开场,commit()方法会调用session.flush()方法,在调用flush()方法时,会首先调用flushEverything()来进行一些预处理(如调用intercepter,完成级联操作等),然后调用flushEntities()方法,这个方法是进行脏数据检查的关键。
在 继续讲解之前,我要先来介绍一个内部数据结构EntityEntry,EntityEntry是从属于SessionImpl(Session接口的实现类)的内部类,每一个EntityEntry保存了最近一次与数据库同步的实体原始状态信息(如:实体的版本信息,实体的加锁模式,实体的属性信 息等)。除了EntityEntry结构之外,还存在一个结构,这个结构称为EntityEntries,它也是SessionImpl的内部类,而且是一个Map类型,它以”key-value”的形式保存了所有与当前session实例相关联的实体对象和原始状态信息,其中key是实体对象,value是EntityEntry。而flushEntities()的工作就是遍历entityEntities,并将其中的实体对象与原始版本进行对比,判断实体对象是否发生来了改变。flushEntities()首先会判断实体的ID是否发生了改变,如果发生了改变则认为发生了异常,因为当前实体与EntityEntry的对应关系非法。如果没有发生异常,而且经过版本比对判断确实实体属性发生了改变,则向当前的更新任 务队列中加入一个新的更新任务,此任务将在将在session.flush()方法中的execute()方法的调用中,转化为相应的SQL语句交由数据库去执行。最后Transaction将会调用当前session对应的JDBC Connection的commit()方法将当前事务提交。

脏 数据检查是发生在显示保存实体对象时,所谓显示保存是指在代码中明确使用session调用save,update,saveOrupdate方法对实体对象进行保存,如:session.save(user);但是有时候由于级联操作的存在,会产生一个问题,比如当保存一个user对象时,会根据user对象的状态来对他所关联的address对象进行保存,但是此时并没有根据级联对象的显示保存语句。此时需要Hibernate能根据当前对象的状态来判断是否要将级联对象保存到数据库中。此时,Hibernate会根据unsaved-value进行判断。Hibernate将首先取出目标对象的ID,然后将ID与unsaved-value值进行比较,如果相等,则认为实体对象尚未保存,进而马上将进行保存,否则,则认为实体对象已经保 存,而无须再次进行保存。比如,当向一个user对象新加入一 个它所关联的address对象后,当进行session.save(user)时,Hibernate会根据unsaved-value的值判断出哪个address对象需要保存,对于新加入的address对象它的id尚未赋值,以此为null,与unsaved-value值相等,因此Hibernate会将其视为未保存对象,生成insert语句加以保存。如果想使用unsaved-value必须如下配置address对象的id属性:

……
<id name=”id” type=”java.lang.Integer” unsaved-value=”null”>
<generator class=”increment”/>
</id>
……
分享到:
评论

相关推荐

    jsp hibernate 数据保存操作的原理.docx

    提交事务时,Hibernate会进行脏数据检查,确定实体对象的哪些属性发生了改变。对于确实发生了变化的属性,Hibernate将构造并执行相应的`UPDATE`语句。 ##### 3. 特别注意事项 需要注意的是,一旦通过`update()`...

    hibernate5--2.数据持久化及事务

    本章节我们将深入探讨Hibernate 5在数据持久化和事务管理方面的特性与用法。 **1. 数据持久化** 数据持久化是通过Hibernate的核心接口Session来实现的。Session提供了对数据库的 CRUD(创建、读取、更新、删除)...

    Hibernate4实战 之第五部分:Hibernate的事务和并发

    这意味着,当你使用 Hibernate 进行数据操作时,所涉及的事务要么基于 JDBC 的事务管理,要么基于 JTA (Java Transaction API)。 **Hibernate 不锁定内存中的对象**。这意味着,当你的应用程序与数据库进行交互时,...

    Hibernate大总结/Hibernate面试题大全

    **StatelessSession** 是Hibernate中提供的另一种Session类型,与普通Session不同,它不具备一级缓存功能,也不参与二级缓存的操作,不会自动进行脏检查等操作。这意味着在使用StatelessSession时,开发者需要手动...

    hibernate_flush 深入了解

    1. **对象状态检查**:Hibernate会检查Session中的所有对象,判断它们是否需要被更新、插入或删除。这包括对持久化对象的脏检查,即比较对象的当前状态和上次持久化时的状态。 2. **生成SQL语句**:根据对象的状态...

    Hibernate框架技术课件ppt

    Hibernate支持脏检查和自动更新,同时引入了二级缓存机制,提高性能。学习者将了解何时启用缓存以及如何配置缓存提供商。 9. 懒加载与立即加载: Hibernate提供了懒加载和立即加载机制来控制关联对象的加载时机,...

    Hibernate(session管理)

    8. **脏检查和自动提交**:Hibernate会定期进行脏检查,检测对象的状态变化,并在事务提交时自动更新数据库。这意味着,只要在事务范围内对对象进行修改,无需显式调用update()方法,Hibernate也会自动处理。 9. **...

    Hibernate 事务和并发控制

    乐观锁假设并发冲突很少发生,通常在数据更新时检查版本号或时间戳,如果发现有其他事务在此期间修改了数据,就回滚事务。在Hibernate中,可以通过在实体类的属性上添加@Version注解来实现乐观锁。 悲观锁则是在...

    精通Hibernate源码.rar

    Hibernate的缓存更新策略包括查询更新、脏检查和版本机制等,确保缓存中的数据与数据库保持同步。例如,乐观锁通过版本字段防止并发更新冲突,而悲观锁则通过数据库的锁定机制来实现。 9. **级联操作** 在映射...

    hibernate的session.flush

    `Session.flush()`的实现涉及到对持久化对象的跟踪、脏检查算法以及与JDBC连接的交互,这些都是深入学习Hibernate时的重要内容。 总结来说,`Session.flush()`是Hibernate中不可或缺的一部分,它确保了数据库与应用...

    jsp hibernate 数据保存操作的原理

    2. **脏数据检查**:在事务提交并清理缓存时,Hibernate会检查对象的脏属性(即发生变化的属性),并生成`UPDATE` SQL语句,更新数据库中的数据。 通过`update()`方法,游离状态的对象重新与Session关联,成为持久...

    hibernate乐观锁和悲观锁学习

    `dirty`通过检测对象的脏属性来判断,而`all`则检查所有属性。由于`version`方式在数据脱离Session后仍然有效,所以它是实际应用中最常用的选择。 在悲观锁中,Hibernate提供了多种锁模式,如`LockMode.NONE`、`...

    Hibernate学习指南pdf

    - **脏检查**: 自动检测对象的状态变化,确保在必要时更新数据库。 - **延迟加载**: 仅在需要时加载关联的对象,优化性能。 - **外键联接**: 支持外键联接的查询,提高查询效率。 - **SQL生成**: 运行时动态生成SQL...

    HIbernate免注解实现操作数据库 及Hibernate3连接SQL的BUG解决办法

    6. **配置错误**: 检查`hibernate.properties`或`hibernate.cfg.xml`文件中的配置项,确保所有必要的属性都已设置,并且值是正确的。 总结来说,虽然注解在现代Hibernate版本中已成为主流,但在特定场景下,使用XML...

    hibernate事务,并发及缓存管理实例

    乐观锁则在更新数据时检查是否被其他事务修改,通常通过版本号或时间戳实现。Hibernate还支持LockMode,包括READ、WRITE、UPGRADE和OPTIMISTIC等,以适应不同级别的并发控制需求。 三、缓存管理 缓存技术可以显著...

    Hibernate Developer Guide

    Hibernate的主要特点包括简化了数据持久化的复杂度,并且支持多种数据库。 #### 二、参与 在开发过程中,可以通过多种方式参与到Hibernate社区中,例如提交bug报告、提出改进意见或贡献代码等。社区的活跃成员还...

    传智播客-hibernate框架开发视频第day01-day04资料

    - 改动追踪与脏检查:理解Hibernate如何检测对象状态的变化,自动执行更新操作。 - 异步操作与事务管理:学习如何在Hibernate中处理并发,以及事务的隔离级别和回滚规则。 4. **Day04:优化与实战** - 查询优化...

    hibernate4.1

    同时,实体状态管理更加智能,可以更好地处理脏检查和变更检测,以提升整体性能。 在配置方面,4.1版本提供了更灵活的XML和基于注解的配置方式。开发者可以选择使用传统的hibernate.cfg.xml文件,或者使用@Entity...

    Hibernate悲观锁和乐观锁的实现

    **乐观锁**(Optimistic Lock)则相对乐观,它假设数据在大多数情况下不会发生冲突,因此在读取数据时不加锁,只有在更新数据时才会检查在此期间数据是否被其他事务修改过。在Hibernate中,乐观锁通常通过版本字段...

Global site tag (gtag.js) - Google Analytics