Hibernate的高级特性.ppt

上传人:xin****828 文档编号:6286757 上传时间:2020-02-21 格式:PPT 页数:19 大小:774.05KB
返回 下载 相关 举报
Hibernate的高级特性.ppt_第1页
第1页 / 共19页
Hibernate的高级特性.ppt_第2页
第2页 / 共19页
Hibernate的高级特性.ppt_第3页
第3页 / 共19页
点击查看更多>>
资源描述
第11章Hibernate的高级特性 11 1Hibernate的事务管理 11 2Hibernate的并发 11 3Hibernate的拦截器 11 1Hibernate的事务管理 11 1 1事务的概念事务有4个重要特性 原子性 即作为一个事务 它是一个不可分割的整体 只有全部操作都完成了 才算结束 其中任何一个操作执行失败 整个事务都要撤销 一致性 即事务不能破坏数据库的完整性和业务逻辑的一致性 事务不管成功还是失败 事务结束时 整个数据库内部数据都是正确的 隔离性 即在并发的数据库操作时 不同的事务操作相同的数据时 每个事务都有自己的完整的数据空间 一个事务不会看到或拿到另一个事务正修改到一半的数据 这些数据要么是另一个事务修改前的 要么是另一个事务修改后提交的 拥有这个特性 是为了在数据库并发操作过程中 保证所有并发操作的正确性 持久性 即事务成功提交后 数据就被永久地保存到数据库 重新启动数据库系统后 数据仍然保存在数据库系统中 11 1 2Hibernate的事务 将事务管理委托给JDBC进行处理是最简单的实现方式 Hibernate对于JDBC事务的封装也比较简单 例如下面的代码 Sessionsession sessionFactory openSession Transactiontx session beginTransaction mit 从JDBC层面而言 上面的代码实际上对应着 Connectioncn getConnection cn setAutoCommit false JDBC调用相关的SQL语句mit 11 1 2Hibernate的事务 在sessionFactory openSession 语句中 Hibernate会初始化数据库连接 与此同时 将其AutoCommit设为关闭状态 false 即一开始从SessionFactory获得的session 其自动提交属性已经被关闭 下面的代码不会对数据库产生任何效果 sessionsession session Factory openSession session save user session close 这实际上相当于JDBCConnection的AutoCommit属性被设为false 执行了若干JDBC操作之后 没有调用commit操作 如果要使代码真正作用到数据库 必须显示地调用Transaction指令 例如下面的代码 Sessionsession sessionFactory openSession Transactiontx sessio beginTransaction session save user mit session close 11 1 2Hibernate的事务 Hibernate的事务应用一般分为下面几个步骤 1 通过SessionFactoy获得Session对象 例如下面的代码 Sessionsession sessionFactory openSession 2 通过Session对象开始一个事务 例如下面的代码 Transactiont session beginTransaction 3 进行相关的数据操作 4 事务提交 例如下面的代码 mit 5 如果事务处理出现异常 则撤销事务 通常叫做事务回滚 例如下面的代码 t rollback 6 关闭Session 结束操作 例如下面的代码 session close 一个完整的应用Hibernate事务的实例 11 1 2Hibernate的事务 2 基于JTA的事务管理概念JTA JavaTransactionAPI 是由JavaEETransactionManager管理的事务 其最大的特点是调用UserTransaction接口的begin commit 和rollback 方法来完成事务范围的界定 事务的提交和回滚 JTA可以实现同一事务对应不同的数据库 JTA主要用于分布式的多个数据源的两阶段提交的事务 而JDBC的Connection提供单个数据源的事务 后者因为只涉及一个数据源 所以其事务可以由数据库自己单独实现 而JTA事务因为其分布式和多数据源的特性 不可能由任何一个数据源实现事务 因此 JTA中的事务是由 事务管理器 来实现的 它会在多个数据源之间统筹事务 具体使用的技术就是所谓的 两阶段提交 JTA事务管理由JTA容器实现 JTA容器对当前加入事务的众多Connection进行调度 实现事务性要求 JTA的事务周期可横跨多个JDBCConnection生命周期 同样 对于基于JTA事务的Hibernate而言 JTA事务横跨多个Session 11 2Hibernate的并发 11 2 1并发产生的问题一般情况下 数据库并发产生的问题可以分为4种 更新丢失 脏读 不可重复读及虚读 下面分别介绍这4种问题 更新丢失 当多个事务同时操作同一数据时 由于事务之间完全没有进行隔离 撤销其中一个事务 结果覆盖了其他事务已经提交并成功更新的数据 对其他事务而言造成了数据丢失 例如 在存款和取款的情况下 如果没有采取措施 很容易出现如表11 1所示的并发问题带来的情况 表11 1更新丢失 11 2 1并发产生的问题 脏读 当多个事务同时操作同一数据时 如果事务A读到事务B尚未提交的更新数据 且对其进行操作 当事务B撤销了更新后 事务A所操作的数据便成了无效数据 即脏数据 同样以存款与取款问题为例 如表11 2所示 表11 2脏读 11 2 1并发产生的问题 虚读 当多个事务同时操作同一数据时 如果事务A在操作过程中进行两次查询 很有可能第二次查询的结果包含了第一次查询中未出现的数据 这里并不要求两次查询的SQL语句相同 这是因为 在两次查询过程中由事务B插入了新数据造成的 如表11 3所示 表11 3虚读 11 2 1并发产生的问题 不可重复读 当多个事务同时操作同一数据时 如果事务A对同一行数据重复读取两次 却得到了不同的结果 有可能在事务A两次读取的过程中 由事务B对该行数据进行了修改 并成功提交 如表11 4所示 表11 4不可重复读 11 2 2解决方案 1 设置隔离级别标准SQL规范中提供了4种事务隔离级别 可以通过Hibernate的配置文件来设置隔离级别 串行化 Serializable 提供严格的事务隔离 它要求各事务串行化执行 事务只能一个接着一个地串行执行 不能并发执行 当数据库采用此隔离级别时 只要有一个事务在操作某个数据 其他欲操作此数据的事务必须停下来等待 直至那个事务结束 有效地防止了所有可能出现的并发问题 但并发性能较低 可重复读取 RepeatableRead 当数据库采用此隔离级别时 一个事务在执行过程中可以访问其他事务成功提交的新插入的数据 但不能访问成功修改的数据 因而有效地防止了不可重复读取和脏读两类并发问题的发生 读已提交数据 ReadCommitted 当数据库采用此隔离级别时 一个事务在执行过程中既可以访问其他事务成功提交的新插入的数据 又可以访问成功修改的数据 因而有效地防止了脏读 读未提交数据 ReadUncommitted 当数据库采用此隔离级别时 一个事务在执行过程中既可以访问其他事务未提交的新插入的数据 又可以访问未提交的修改数据 因而仅仅防止了更新丢失的发生 11 2 2解决方案 2 锁Hibernate支持两种锁机制 悲观锁 PessimisticLocking 和乐观锁 OptimisticLocking 悲观锁是指对数据被外界修改持保守态度 假定任何时刻存取数据时 都可能有一个客户也正在存取同一数据 为了保持数据被操作的移植性 于是对数据采取了数据库层次的锁定状态 依靠数据库提供的锁机制来实现 乐观锁则乐观地认为数据很少发生同时存取的问题 因而不做数据库层次上的锁定 为了维护正确的数据 乐观锁采用应用程序上的逻辑实现版本控制的方法 Hibernate中以通过版本号检索来实现更新为主 这也是Hibernate推荐的方式 在数据库中假如有一个Version记录 在读取数据时连带版本号一同读取 并在更新数据时递增版本号 然后比较此版本号和数据库中的版本号 如果大于数据库中的版本号 则给予更新 否则就报错误 11 3Hibernate的拦截器 11 3 1Interceptor接口下面分别介绍这些方法的含义及执行阶段 afterTransactionBegin Transactiontx 当Hibernate事务被调用后 该方法将被调用 afterTransactionCompletion Transactiontx 当事务被提交或回滚后 该方法被调用 beforeTransactionCompletion Transactiontx 该方法在一个事务提交前被调用 但是回滚前不被调用 findDirty Objectentity Serializableid Object currentState Object previousState String propertyNames Type types 当调用flush 方法刷新缓存时会自动调用这个方法检查缓存中是否有脏数据 缓存中有数据库不一致的数据 返回的数组是对象脏属性的索引 如果该数组不为空 说明这个对象需要被更新 如果是空的数组 说明这个对象不必被更新 默认返回null Hibernate会自动使用默认的方式检查对象是否是脏数据 onDelete ObjectSerializableid Object state String propertyName Type types 在对象删除前被调用 不建议使用给 state 参数赋值来修改要被删除实体的属性值 11 3 1Interceptor接口 onFlushDirty Objectentity Serializableid Object currentState Object previousState String propertyNames Type types 如果一个对象在flush执行时被发现是脏数据 则这个方法会被调用 可以给 currentState 参数赋值 这个赋值既会修改持久化类对象的属性值 也会修改数据库表对应的列值 不建议使用给 previousState 赋值来修改实体更新前的属性值 返回值是boolean类型 true说明在方法体中修改了对象的属性值 currentState false说明没有修改其当前属性值 onLoad Objectentity Serializableid Object state String propertyNames Typ types 当一个对象从数据库中载入时被调用 修改 state 参数 就可以修改持久化类对象的属性值 返回值是boolean类型 true说明在方法体中修改了对象的属性值state false表示没有修改 onSave Objectentity Serializableid Object state String propertyNames Type types 在一个方法保存之前被调用 如果给相应的 state 赋值 这个值能够被insert语句保存到数据库中 同时也更改持久化类对象的属性值 返回boolean类型 true代表用户在其中修改了属性值state false表示没有修改 11 3 1Interceptor接口 onCollectionRecreate Objectcollection Serializablekey 在集合被创建或再次创建时被调用 如果一个持久化类中使用了Java集合属性 那么保存这个持久化类时 这个集合属性中的元素也被同时保存 这个onCollectionRecreate 方法会被自动调用 onCollectionRemove Objectcollection Serializablekey 在集合被删除时被调用 onCollectionUpdate Objectcollection Serializablekey 在集合被更新时被调用 isTransient Objectentity 调用这个方法可以判断一个实体是持久化态还是游离态 返回值是boolean类型 如果返回true 代表这个实体是持久化态 如果返回false 代表这个实体是游离态 如果返回null 说明Hibernate使用映射文件中的unsaved value或者其他方法来判断 这个实体还没有被保存 是临时态 getEntity StringentityName Serializableid 以对象名字和id为参数 可以返回持久化对象实体 getEntityName Objectobject 以持久态和游离态的实体类对象为参数 可以返回实体的名字 11 3 1Interceptor接口 instantiate StringentityName EntityModeentityMode Serializableid 这个方法可以显式地让Hibernate实例化一个实体类 参数entityName是实体对象的名字 entityMode是返回的实体实例的类型 参数id将作为新实体对象的id onPrepareStatement Stringarg0 这个方法可以返回要执行的SQL语句 参数arg0即是要执行的SQL语句 postFlush Iteratorarg0 该方法在持久化所做修改同步完成后会执行 preFlush Iteratorarg0 该方法在同步持久化所做修改之前会执行 11 3 2应用举例 创建Hibernate程序Hibernate Interceptor 添加Hibernate的类库 核心类库 及数据库驱动 创建配置文件 代码 本例实现对数据库中userTable表的操作 故POJO类及映射文件如下 User java代码为 packageorg vo publicclassUser privateintid privateStringusername privateStringpassword 省略上面属性的get和set方法 11 3 2应用举例 映射文件User hbm xml代码为 下面编写拦截器 代码 11 3 2应用举例 编写测试类Test java 代码 运行该测试程序 结果如下 该语句在事务开始之后执行 保存持久化实例时调用该方法这里返回要执行的SQL语句Hibernate insertintouserTable username password values 在同步持久化所做修改之前调用该方法持久化所做修改同步完成后 调用该方法该语句在事务提交前被执行 回滚前不执行 该语句在事务提交或回滚后执行
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!