《Hibernate事务处理.ppt》由会员分享,可在线阅读,更多相关《Hibernate事务处理.ppt(24页珍藏版)》请在三一办公上搜索。
1、Hibernate事务处理,开源O/R映射框架,数据库事务介绍事务的定义事务的ACID属性数据库事务声明通过Hibernate声明JDBC事务通过Hibernate声明JTA事务并发控制多个事务并发引起的问题事务隔离级别在应用程序中解决不可重复读问题乐观锁(Optimistic Locking)悲观锁(Pessimistic Locking),Java高端培训,2,数据库事务的定义,事务是指一组相互信赖的操作行为。这些操作要么必须全部成功,要么必须全部失败,以保证数据的一致性和完整性。数据库事务是对现实生活中事务的模拟,它由一组在业务逻辑上相互信赖的SQL语句组成。示例:银行转帐操作。,Jav
2、a高端培训,3,数据库事务的ACID属性,ACID:原子性(Atomic):指整个数据库事务是不可分割的工作单元。原子性确保在事务中的所有操作要么都发生,要么都不发生。一致性(Consistency):一旦一个事务结束了(不管成功与否),系统所处的状态和它的业务规则是一致的。即数据应当不会被破坏。隔离性(Isolation):指多个事务同时操作同一数据时,每个事务都有各自的完整数据空间。持久性(Durability):一旦事务完成,事务的结果应该持久化。,Java高端培训,4,数据库事务声明,Java高端培训,5,数据库事务声明,数据库系统的客户程序只要向数据库系统声明了一个事务,数据库系统就
3、会自动保证事务的ACID特性。声明事务包含:事务的开始边界:开始事务。事务的正常结束边界:提交事务。事务的异常结束边界:回滚事务。数据库系统支持两种事务模式:自动提交事务(隐式事务):每个SQL语句都是一个独立的事务,当数据库系统执行完一条SQL语句后,会自动提交事务。手工提交事务(显式事务):必须由数据库系统的客户程序显式指定事务开始边界和结束边界。,Java高端培训,6,回顾通过JDBC声明事务,Java高端培训,7,Connection con=null;PreparedStatement pstmt=null;try con=DriverManager.getConnection(db
4、Url,username,password);/设置手工提交事务模式 con.setAutoCommit(false);pstmt=;pstmt.executeUpdate();/提交事务 mit();catch(Exception e)/事务回滚 con.rollback();.finally.,通过Hibernate声明事务,Hibernate本身在设计时并不具备事务处理功能Hibernate只是将底层的JDBCTransaction或者JTATransaction进行了一下封装,在外面套上Transaction和Session的外壳,其实底层都是通过委托底层的JDBC或JTA来实现事务的
5、调度功能。,Java高端培训,8,通过Hibernate声明JDBC事务,如果Hibernat持久层运行在一个非托管环境中,可以在hibernate配置文件中指定使用的是JDBC事务。注:如果不进行配置,Hibernate也会默认使用JDBC事务。,Java高端培训,9,org.hibernate.transaction.JDBCTransactionFactory,hibernate.cfg.xml,Transaction tx=null;try tx=session.beginTransaction();/do some work.mit();catch(RuntimeException
6、e)if(tx!=null)tx.rollback();throw e;/or display error messagefinally session.close();,注意事项,不管事务成功与否,最后都应该调用Session的close()方法来关闭Session。即使事务中只包含只读操作,也应该在事务执行成功后提交事务,并且在事务执行失败时撤销事务。因为在提交或撤销事务时,数据库会释放事务所占用的资源,有利于提高数据库的运行性能。一个Session可以包含多个Transaction实例,也就是说,一个Session可以对应多个事务。如果在执行Session的一个事务时出现了异常,就必须立
7、即关闭这个Session,不能再利用这个Session来执行其他的事务。,Java高端培训,10,通过Hibernate声明JTA事务,Hibernat持久层运行在一个托管环境中,可以使用JTA,Java高端培训,11,org.hibernate.transaction.JTATransactionFactory,/BMT(bean管理事务)UserTransaction tx=null;try tx=(UserTransaction)new InitialContext().lookup(java:comp/UserTransaction);tx.begin();/Do some work
8、on Session bound to transaction factory.getCurrentSession().persist(.);mit();catch(RuntimeException e)tx.rollback();throw e;/or display error message,hibernate.cfg.xml,注:在CMT(容器管理事务)方式下,事务声明是在session bean的部署描述符中,而不需要编程。,并发控制多个事务并发引起的问题事务隔离级别在应用程序中解决不可重复读问题乐观锁(Optimistic Locking)悲观锁(Pessimistic Locki
9、ng),Java高端培训,12,多个事务并发引起的问题,多个事务同时访问数据库中相同的数据时,如果没有采取必要的隔离机制,就可能会发生如下并发问题:第一类丢失更新:撤消一个事务时,把其它事务已提交的更新数据也撤消了。脏读:一个事务读到另一个事务未提交的更新数据。不可重复读:一个事务读到另一个事务已经提交的更改数据。第二类丢失更新:一个事务覆盖另一个事务已经提交的更新数据。幻读:一个事务读到另一个事务已提交的新增或已删除数据。,Java高端培训,13,数据库事务隔离级别,为了解决多个事务并发会引发的问题,让用户根据需要在事务的隔离性和并发性之间做合理的权衡,数据库系统提供了四种事务隔离级别供用户
10、选择:Read Uncommitted(读未提交数据):它可以防止第一类丢失更新问题,但没有解决脏读以上的并发问题。它的事务隔离性最低。Read Committed(读已提交数据):它可以防止脏读以下的并发问题,但没有解决不可重复读以上的并发问题。Repeatable Read(可重复读):它可以防止不可重复读(包括第二类丢失更新)以下的并发问题,但没有解决幻读问题。Serializable(串行化):提供最严格的事务隔离性。它把事务隔离成连续的一个接一个地执行,而不是并发执行。在这种隔离级别下,不会出现任何的并发问题。,Java高端培训,14,各种隔离级别所能避免的并发问题,隔离级别越高,越
11、能保证数据的完整性和一致性,但对并发性能的影响也越大。对于多数应用,可能优先考虑把数据库系统的隔离级别设为Read Committed,它能够避免脏读,而且具有较好的并发性能。,Java高端培训,15,在应用程序中设置隔离级别,每个数据库连接都有一个全局变量tx_isolation表示当前的事务隔离级别。JDBC使用数据库系统默认的隔离级别。在非托管环境下:Hibernate配置文件中可以显示地设置隔离级别。每一种隔离级别对应着一个正整数:Read Uncommitted:1Read Committed:2Repeatable Read:4Serializable:8在hibernate配置文
12、件中设置隔离级别方式:,Java高端培训,16,2,托管环境的隔离级别设置,在受管理环境中,如果Hibernate使用的数据库连接来自于应用服务器提供的数据源,Hibernate不会改变这些连接的事务隔离级别。这种情况下,应该通过修改应用服务器的数据源配置来修改隔离级别。,Java高端培训,17,解决不可重复读问题,当数据库系统采用Red Committed隔离级别时,会导致不可重复读和第二类丢失更新的并发问题。在可能出现这种问题的场合,可以在应用程序中采用乐观锁或悲观锁来避免这类问题。,Java高端培训,18,乐观锁(Optimistic Locking),乐观锁假定当前事务操纵数据资源时,
13、不会有其他事务同时访问该数据资源,因此不作数据库层次上的锁定。为了维护正确的数据,乐观锁使用应用程序上的版本控制(由程序逻辑来实现的)来避免可能出现的并发问题。唯一能够同时保持高并发和高可伸缩性的方法就是使用带版本化的乐观并发控制。版本检查使用版本号()或者时间戳()来检测更新冲突并防止更新丢失。,Java高端培训,19,使用进行版本控制,原理:在数据库表中加入一个version(版本)字段,在读取数据时连同版本号一起读取。在更新数据时先比较新数据的版本号与数据库表中的版本号:如果等于数据库表中的版本号则予以更新,并递增版本号。如果小于数据库表中的版本号就抛出异常。Hibernate在其数据库
14、访问引擎中内置了乐观锁定实现,默认也是选择version方式作为Hibernate乐观锁定实现机制。步骤:在持久化类中定义一个代表版本号的属性。类型:long,integer,short在对象关系映射文件中用标记来建立持久化类的version属性与表中version字段的映射,一定要定义在元素后面。完成以上两个步骤后,在配置文件及程序中就无须作其它设置,按往常一样写操作代码就可以了。,Java高端培训,20,示例,Java高端培训,21,public class Product implements java.io.Serializable private Long id;private in
15、t version;/版本号 private String name;/产品名 private String description;/描述-简介 private Double unitCost;/单价 private Date pubTime;/生产日期.,Product.java,Product.hbm.xml,注意事项,使用时间戳()也可以完成乐观锁定机制,但不是特别安全的实现。用法跟版本检查相似。由于乐观锁定是使用系统中的程序来控制,而不是使用数据库中的锁定机制,因而如果有人故意自行更新版本信息来越过检查,则锁定机制就无效。所以建议把持久化类中的version属性的set方法设置为pr
16、ivate的。,Java高端培训,22,悲观锁(Pessimistic Locking),悲观锁假定当前事务操纵数据资源时,肯定还会有其他事务同时访问该数据资源,为了避免当前事务的操作受到干扰,先锁定资源。悲观锁的一般实现方式是:在应用程序中显式采用数据库系统的独占锁来锁定数据资源。在如下几种方式时可能显示指定锁定模式为LockMode.UPGRADE:调用Session的get()或load()时调用Session的lock()方法时调用Query的setLockMode()方法它会生成 select.for update 这样的语句来显示指定采用独占锁来锁定查询的记录。尽管悲观锁能够防止丢失更新和不可重复读这类并发问题,但是它影响并发性能,因此应该很谨慎地使用悲观锁。,Java高端培训,23,session.load(Product.class,new Long(1),LockMode.UPGRADE);,总结,数据库事务介绍事务的定义事务的CAID属性数据库事务声明通过Hibernate声明JDBC事务通过Hibernate声明JTA事务并发控制多个事务并发引起的问题事务隔离级别在应用程序中解决不可重复读问题乐观锁(Optimistic Locking)悲观锁(Pessimistic Locking),Java高端培训,24,