第11章 Hibernate高级特性_第1页
第11章 Hibernate高级特性_第2页
第11章 Hibernate高级特性_第3页
第11章 Hibernate高级特性_第4页
第11章 Hibernate高级特性_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、11.1 Hibernate事务管理事务管理11.2 Hibernate并发处理并发处理11.3 Hibernate的拦截器的拦截器11.1.1 事务的概念事务的概念事务有4个重要特性。 原子性:即作为一个事务,它是一个不可分割的整体,只有全部操作都完成了,才算结束;其中任何一个操作执行失败,整个事务都要撤销。 一致性:即事务不能破坏数据库的完整性和业务逻辑的一致性。事务不管成功还是失败,事务结束时,整个数据库内部数据都是正确的。 隔离性:即在并发数据库操作中,不同事务操作相同的数据时,每个事务都有自己完整的数据空间。一个事务不会看到或拿到另一个事务正修改到一半的数据,这些数据要么是一个事务修

2、改前的,要么是另一个事务修改后提交的。拥有这个特性,是为了保证所有并发操作的正确性。 持久性:即事务成功提交后,数据就被永久地保存到数据库,重新启动数据库系统后,数据仍然保存在数据库系统中。1基于基于JDBC的事务管理的事务管理将事务管理委托给JDBC进行处理是最简单的实现方式,Hibernate对于JDBC事务的封装也比较简单。例如下面的代码:Session session = sessionFactory.openSession();Transaction tx=session.beginTransaction();mit();从JDBC层面而言,上面的代码实际上对应着:Connectio

3、n cn = getConnection;cn.setAutoCommit(false);/ JDBC调用相关的SQL语句mit();在sessionFactory.openSession()语句中,Hibernate会初始化数据库连接。与此同时,将其AutoCommit设为关闭状态(false),即一开始从SessionFactory获得的session,其自动提交属性已经被关闭。下面的代码不会对数据库产生任何效果:session session = sessionFactory.openSession();session.save(user);session.close();这实际上相当于

4、JDBC Connection的AutoCommit属性被设为false,执行了若干JDBC操作之后却并没有调用commit操作。如果要使代码真正作用到数据库,必须显式地调用Transaction指令,例如下面的代码:Session session = sessionFactory.openSession();Transaction tx = session.beginTransaction();session.save(user);mit();session.close();Hibernate的事务应用一般分为下面几个步骤。(1)通过SessionFactoy获得Session对象,例如下面

5、的代码:Session session = sessionFactory.openSession();(2)通过Session对象开始一个事务,例如下面的代码:Transaction t = session.beginTransaction();(3)进行相关的数据操作。(4)事务提交,例如下面的代码:mit();(5)如果事务处理出现异常,则撤销事务(通常称为事务回滚),例如下面的代码:t.rollback();(6)关闭Session,结束操作,例如下面的代码:session.close();综上,一个完整的应用Hibernate事务的实例如下:.Configuration cfg = n

6、ew Configuration().configure();SessionFactory sessionFactory = cfg.buildSessionFactory();Session session = sessionFactory.openSession();Transaction t = session.beginTransaction();tryUserTable user = new UserTable();user.setUsername(Jack);user.setPassword(123456);session.save(user);mit();catch(Except

7、ion e)if(t!=null)t.rollback();e.printStackTrace();finallysession.close();.2基于基于JTA的事务管理的事务管理JTA(Java Transaction API)是由Java EE Transaction Manager管理的事务,其最大的特点是调用UserTransaction接口的begin()、commit()和rollback()方法来完成事务范围的界定、事务的提交和回滚。JTA可以实现同一事务对应不同的数据库。JTA主要用于分布式多个数据源的两阶段提交的事务,而JDBC的Connection提供单个数据源的事务,

8、后者因为只涉及一个数据源,所以其事务可以由数据库自己单独实现,而JTA事务因为其分布式和多数据源的特性,不可能由任何一个数据源实现事务。JTA提供了跨Session的事务管理能力,这一点是与JDBC Transaction最大的差异。JTA事务管理由JTA容器实现,JTA容器对当前加入事务的众多Connection进行调度,实现事务性要求。JTA的事务周期可横跨多个JDBC Connection生命周期。11.2.1 并发产生的问题并发产生的问题1. 更新丢失更新丢失当多个事务同时操作同一数据时,由于事务之间完全没有进行隔离,撤销其中一个事务,结果覆盖了其他事务已经提交并成功更新的数据,对其他

9、事务而言造成了数据丢失。例如,在存款和取款的情况下,如果没有采取措施,很容易出现如表11.1所示的并发问题带来的情况。阶 段取 款存 款1事务开始2查询账户余额1000元3事务开始4查询账户余额1000元5取走100元,剩余900元6存入100元,账户中应为1100元7提交事务8撤销事务,账户余额回滚为事务开始时的1000元,事务结束2脏读脏读当多个事务同时操作同一数据时,如果事务A读到事务B尚未提交的更新数据,且对其进行操作,当事务B撤销了更新后,事务A所操作的数据便成了无效数据(脏数据)。同样以存款取款问题为例,如表11.2所示。阶 段取 款存 款1事务开始2查询账户余额1000元3事务开

10、始4取走100元,剩余900元5查询账户余额900元6存入100元,账户中应为1000元7提交事务8撤销事务,账户余额回滚为事务开始时的1000元,事务结束3虚读虚读当多个事务同时操作同一数据时,如果事务A在操作过程中进行两次查询,很有可能第二次查询的结果包含了第一次查询中未出现的数据(这里并不要求两次查询的SQL语句相同)。这是因为,在两次查询过程中由事务B插入了新数据造成的,如表11.3所示。阶 段存 款查 询1事务开始2事务开始3查询账户余额1000元4存入100元,账户中应为1100元5提交事务6再次查询,账户余额为1100元7不知到底是1100元还是1000元4不可重复读不可重复读当

11、多个事务同时操作同一数据时,如果事务A对同一行数据重复读取两次,却得到了不同的结果,有可能在事务A两次读取的过程中,由事务B对该行数据进行了修改,并成功提交,如表11.4所示。阶 段取 款存 款1事务开始2查询账户余额1000元3事务开始4查询账户余额1000元5存入100元,余额应为1100元6存入100元,账户中应为1100元7提交事务,账户余额为1100元8提交事务,账户余额为1100元1隔离级别隔离级别标准SQL规范中提供了4种事务隔离级别,可以通过Hibernate的配置文件来设置。 串行化(Serializable):提供严格的事务隔离。它要求各事务串行化执行,事务只能一个接着一个

12、地串行执行,不能并发执行。 可重复读取(Repeatable Read):当数据库采用此隔离级别时,一个事务在执行过程中可以访问其他事务成功提交的新插入的数据,但不能访问成功修改的数据,因而有效地防止了不可重复读取和脏读两类并发问题的发生。 读已提交数据(Read Committed):当数据库采用此隔离级别时,一个事务在执行过程中既可以访问其他事务成功提交的新插入的数据,又可以访问成功修改的数据,因而有效地防止了脏读。 读未提交数据(Read Uncommitted):当数据库采用此隔离级别时,一个事务在执行过程中既可以访问其他事务未提交的新插入的数据,又可以访问未提交的修改数据,因而仅仅防

13、止了更新丢失的发生。2锁锁业务逻辑的实现过程中,往往需要保证数据访问的排他性,如在金融系统的日终结算处理中,希望对某个结算时间点的数据进行处理,而不希望在结算过程中(可能是几秒,也可能是几个小时)数据再发生变化。此时,需要通过一些机制来保证这些数据在某个操作过程中不会被外界修改,这样的机制就是所谓的“锁”,即给选定的目标数据上锁,使其无法被其他程序修改。Hibernate支持两种锁机制:悲观锁(Pessimistic Locking)和乐观锁(Optimistic Locking)。悲观锁是指对数据被外界修改持保守态度。假定任何时刻存取数据时,都可能有一个客户也正在存取同一数据,为了保持数据被

14、操作的一致性,于是对数据采取了数据库层次的锁定状态,依靠数据库提供的锁机制来实现。11.3.1 Interceptor接口接口Interceptor接口中定义了各种事件对应的方法,不同的方法在对应的事件发生时将会被Hibernate自动调用。下面分别介绍这些方法的含义及执行阶段。 afterTransactionBegin(Transaction tx):当Hibernate事务被调用后,该方法将被调用。 afterTransactionCompletion(Transaction tx):当事务被提交或回滚后,该方法被调用。 beforeTransactionCompletion(Trans

15、action tx):该方法在一个事务提交前被调用,但是回滚前不被调用。 findDirty(Object entity,Serializable id, Object currentState, Object previousState,String propertyNames, Type types):当调用flush()方法刷新缓存时会自动调用这个方法检查缓存中是否有脏数据(缓存中有与数据库不一致的数据)。 onDelete(ObjectSerializable id,Object state, String propertyName,Type types):在对象删除前被调用。 onF

16、lushDirty(Object entity,Serializable id, Object currentState, Object previousState, String propertyNames, Type types):如果一个对象在flush执行时被发现是脏数据,则这个方法会被调用。 onLoad(Object entity,Serializable id,Object state,String propertyNames,Typtypes):当一个对象从数据库中载入时被调用。 onSave(Object entity,Serializable id,Object state

17、,String propertyNames,Typetypes):在一个方法保存之前被调用。 onCollectionRecreate(Object collection, Serializable key):在集合被创建或再次创建时被调用。 onCollectionRemove(Object collection, Serializable key):在集合被删除时被调用。 onCollectionUpdate(Object collection, Serializable key):在集合被更新时被调用。 isTransient(Objectentity):调用这个方法可以判断一个实体是持

18、久态还是脱管态。 getEntity(String entityName, Serializable id):以对象名字和id为参数,可以返回持久化对象实体。 getEntityName(Objectobject):以持久态和脱管态的实体类对象为参数,可以返回实体的名字。 instantiate(String entityName, EntityMode entityMode, Serializable id):这个方法可以显式地让Hibernate实例化一个实体类。 onPrepareStatement(String arg0):这个方法可以返回要执行的SQL语句,参数arg0即是要执行的SQL语句。 postFlush(Iterator arg0):该方法在持久化所做修改同步完成后会执行。 preFlush(Iterator arg0):该方法在同步持久化所做修改之前会执行。【实例实例11.1】Hibernate拦截器应用示例。1创建创建Hibernate程序程序创建Java项目,命名为Hibernate_Interceptor。添

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论