
在Hibernate中,事务是并发控制的基本单位。所谓的事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。 事务是指一组相互依赖的操作行为,在每个事务结束时,都能保持数据一致性。事务是指作为单个逻辑工作单元执行的一系列操作。数据库向用户提供保存当前程序状态的方法叫事务提交;当事务执行过程中,是数据库忽略当前的状态并回到前面保存的状态的方法叫事务回滚。
(1)A:表示Atomic(原子性):是指整个数据库事务是一个不可分割的工作单元,只有事务中每个操作都执行成功后,事务才算成功。 (2)C:表示Consistency(一致性):是指数据库事务不能破坏关系数据的完整性和业务逻辑的一致性,例如转账,应保证事务结束后两个账户的存款总额不变。 (3)I:表示Isolation(隔离性):在并发环境中,当不同的事务操作相同的数据时,都应该有自己的一个完整的数据空间。 (4)D:表示Durability(持久性):指只要事务成功结束,对数据库的更新就必须永久保存下来,即使系统发生崩溃,重启数据库后,数据库还能恢复到事务成功结束时的状态。
悲观锁指的是当数据被外界(包括本系统当前的其他业务,以及来自外部系统的事务处理)修改时保持原始状态,因此,在整个数据处理过程中,将数据处于锁定状态。 一个典型的依赖数据库的悲观锁调用:
SELECT * FROM student WHERE NAME = 'Lily' FOR UPDATE;这条SQL语句锁定了student表中所有符合检索条件(name=”Lily”)的记录。本次事务提交之前(事务提交时会释放事务过程中的锁),外界无法修改这些记录。Hibernate的悲观锁,也是基于数据库的锁机制实现的。
乐观锁的工作原理:读取出数据时,将此版本号一同读出,之后更新时,对版本号加一。此时,将提交数据的版本数据与数据库表对应的记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。 在Hibernate中,主要由Hibernate提供的版本控制功能来实现乐观锁定。Hibernate为乐观锁提供了两种实现,分别为基于version的实现和基于timestamp的实现。对象关系映射文件中的version元素和timestamp元素,都具有版本控制功能。Version元素利用一个递增的整数来跟踪数据库表中记录的版本;而timestamp元素则用时间戳来跟踪数据库中表中记录的版本。
缓存是计算机领域中非常通用的概念,介于应用程序和永久性数据存储源之间。缓存的作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能。
(1)事务范围:缓存只能被当前事务访问。 (2)进程范围:缓存被进程内的所有事务共享。 (3)集群范围:在集群环境中,缓存被一个计算机或者多个计算机的进程共享。
第一级别的缓存是Session级别的缓存,它是属于事务范围的缓存。这一级别的缓存由Hibernate管理的,一般情况下无需进行干预;一级缓存释session所内置的,不能被卸载,也不能进行任何配置。 第二级别的缓存是SessionFactory级别的缓存,它是属于进程范围或群集范围的缓存。这一级别的缓存可以进行配置和更改,并且可以动态加载和卸载。二级缓存是一个可拔插的缓存插件,它是由SessionFactory负责管理。
当多个并发的事务同时访问持久化层中缓存的相同数据时,会引起并发问题,必须采用必要的事务隔离措施。在进程范围或集群范围的缓存,即第二级缓存,会出现并发问题。因此可以设定以下四种类型的并发访问策略,每一种策略对应一种事务隔离级别。 (1)事务型策略:仅仅在受管理环境中适用。提供了Repeatable Read事务隔离级别。对于经常被读但很少修改的数据,可以采用这种隔离类型,因为可以防止脏读和不可重复读这类的并发问题。 (2)读写型策略:提供了Read Committed事务隔离级别。仅仅在非集群环境中适用。对于经常被读但很少修改的数据,可以采用这种隔离类型,因为可以防止脏读并发问题。 (3)非严格读写型策略:不保证缓存与数据库中数据的一致性。如果存在两个事务,同时访问缓存中相同数据的可能,必须为该数据配置一个很短的数据过期时间,从而尽量避免脏读。对于极少被修改,并且允许偶尔脏读的数据,可以采用这种并发访问策略。 (4)只读型策略:对于从来不会修改的数据,如参考数据,可以使用这种并发访问策略。事务型并发访问策略是事务隔离级别最高,只读型的隔离级别最低。事务隔离级别越高,并发性能就越低。
对于经常使用的查询语句,如果启用了查询缓存,当第一次执行查询语句时,Hibernate把查询结果存储在第二级缓存中。以后再次执行该查询语句时,则从缓存中获得查询结果,从而提高查询性能。适用于以下场合: (1) 在应用程序运行时经常使用的查询语句。 (2) 很少对于查询语句关联的数据库数据进行插入、删除或更新操作。