一、Session在什么情况下清理缓存
?
答:
1 、当应用程序调用Transaction.Commit()方法的时候,先清理缓存,然后再向数据库提交事务。
2 、当应用程序调用Session.Find()或者Iterate()方法时,如果缓存中的持久化对象的属性发
生了变化,就会先清理缓存,以保证查询的结果能反映持久化对象的最新状态。
3 、当应用程序显式调用Session.Flush()方法的时候。
注意:Session进行清理缓存的例外情况是,如果对象使用native生成器来生成OID,那么当调用Session的Save()
方法保存该对象时,会立即执行向数据库插入该实体的insert语句
二、Session在清理缓存时,会按照什么顺序来执行Sql语句 ?
答:
1 、按照应用程序调用Session.Save()方法的先后顺序,执行所有对实体进行插入的insert语句。
2 、执行所有对实体进行更新的update语句。
3 、执行所有对集合进行删除的delete语句。
4 、执行所有对集合元素进行更新、删除、插入的sql语句。
5 、执行所有对集合进行插入的insert语句。
6 、按照应用程序调用Sesson.delete()方法的先后顺序,执行所有对实体进行删除的delete语句。
三、Session清理缓存的三种模式
清理缓存的模式 FlushMode.Auto FlushMode.Commit FlushMode.None
Session查询方法 清理 不清理 不清理
Session的Commit方法 清理 清理 不清理
Session的Flush方法 清理 清理 清理
四、Session的SaveOrUpdate方法如何工作,如何判断一个对象是临时对象还是游离对象 ?
答:如何传入的参数是临时对象就调用Save()方法;如果传入的对象是游离对象,就调用Update()方法;如果传入的参数是持久化对象就直接返回。
Hibernate判断临时对象的标准:
1 、 实体对象OID为null
2 、 实体对象具有version属性并且取值为null
3 、 在映射文件中为 < id > 元素设置了unsaved - value属性,并且OID取值与unsaved - value属性值匹配。
4 、 自定义Hibernate的Interceptor实现类,并且Interceptor的isUnsaved()方法返回Boolean.True。
五、在进行对象级联的时候有一个cascade属性,这个属性的属性值代表什么意义 ?
cascade属性值
描述
none
在保存、更新或者删除对象时,忽略其他关联的对象,它是级联的默认值
save - update
当通过Session的Save()、Update()以及SaveOrUpdate()方法来保存、更新对象时,级联保存关联的临时对象,并更新关联的游离对象。
delete
当通过Session的Delete()方法删除当前对象时,同时会删除关联的所有对象。
all
包含save - update以及delete的行为,此外对当前对象进行Evict()或者Lock()方法时会对关联的对象进行同样的操作。
delete - orphan
删除所有和当前对象解除关联关系的对象。
all - delete - orphan
包含all和delete - orphan的行为。
六、Hibernate在与触发器协同工作的时候如何保持数据的同步 ?
答:当Session执行Save()方法、SaveOrUpdate()方法、Update()方法时立即执行Session的Reflush()方法,直接绕过Session缓存从数据库中加载数据,
七、如何改变Hibernate操作持久化对象的行为 ?
答:通过对拦截器接口的实现改变Session的操作行为。
八. Hibernate缓存的种类 ?
答:分为内置缓存和外置缓存两种.
内置缓存的分类:
1 、Session中的内置缓存,这个是Hibernate缓存不可缺的组成部分,将持久化对象缓存到Session中
2 、SessionFactory中的内置缓存,这个是Hibernate缓存不可缺的组成部分,将一些数据库操作的
Sql语句缓存起来。这个缓存是只读的
持久化层的缓存的范围:
1 、事务范围:Session的内置缓存就是一个事务范围的,也就是缓存的生命周期随着事务的建立而产生,
随着事务的结束而消亡。
2 、进程范围:缓存被进程内的所有事务共享,这些事务由可能并发访问缓存,因此必须对进程范围的缓存
提供事务隔离机制。
3 、集群范围:缓存被同一个机器或多个机器上的多个进程共享。对于大多数应用要慎重考虑集群范围的缓存
由于并发的原因对应用性能影响较大。一般将只读的数据或者很少修改的数据存储到集群范围的缓存中。
外置缓存的支持:
Hibernate提供了EBCache、OSCache、SwarmCache、JBossCache这些第三方插件的适配器。具体的配置方法
请查看相关的文档。
注意:在对数据进行批量处理的时候为了提高性能还是直接通过Hibernate调用底层的数据库操作API。
数据库事务与并发
概述:事务通过隔离级别控制锁的形式来处理数据的并发问题。
九。为什么事务能够处理并发问题?
答:事务的特性决定它能够处理并发问题:一致性、隔离性、持久性、原子性
数据的并发有哪些情况?
答:
一、后发生的事务影响前面的事务
1 、第一类更新丢失:后发生的事务回滚覆盖了前面提交成功的事务
2 、脏读:后发生的事务成功提交覆盖了前面的回滚的事务
3 、第二类更新丢失:后发生的事务成功提交覆盖了前面的成功提交的事务
二、后发生的事务受到前面的事务的影响
1 、虚读:后一个事务在前后两次读取数据时由于前面的已提交的事务进行了插入操作,
而使数据统计前后不一致。
2 、不可重复读:后一个事务在对同一条数据前后两次读取时由于前面的已提交的事务
进行了对这条数据更新操作,而使数据前后不一致。
事务如何处理并发问题?
答:
事务通过锁来处理并发问题一般有两种方式:
悲观锁:通过数据库系统的锁来处理并发
乐观锁:通过应用程序逻辑处理并发
悲观锁的种类有哪些?
答:
一、共享锁:用于读数据操作。
特性:
1 、加锁条件:当一个事务执行select语句时数据库系统会为这个事务分配一把共享锁,来锁定被查询的记录。
2 、解锁条件:读取完毕则释放共享锁。
3 、兼容性:如果数据资源上已经放了共享锁还可放共享锁和更新锁。
4 、并发性能:具有良好的并发性能。
二、更新锁:在更新操作的初始化阶段用来锁定可能要被修改的资源,避免使用共享锁造成的死锁问题。
特性:
1 、加锁条件:当一个事务执行update语句时,数据库系统会先为事务分配一个更新锁。
2 、解锁条件:当读取数据完毕,进行更新操作时将更新锁升级为独占锁。
3 、兼容性:与共享锁兼容。一个数据资源上可以有多个共享锁和一个更新锁。
4 、允许多个事务同时读锁定的资源,但不允许其它事务修改它。
三、独占锁:修改数据时使用独占锁。
特性:
1 、加锁条件:当执行update、delete、insert操作时数据库系统会为数据资源使用独占锁。如果该资源上已经有其它锁
存在时则无法放置独占锁
2 、解锁条件:独占锁一直到事务结束才能被解除。
3 、兼容性:独占锁不能和其它锁兼容。
4 、并发性:并发性能较差。
事务如何控制锁的形式?
答:事务通过事务的隔离级别来控制锁的形式。
事务级别有哪些?并发情况怎样?
答:
隔离级别 是否出现第一类丢失更新 是否出现脏读 是否出现虚读 是否出现不可重复读 是否出现第二类丢失更新
Serializable 否 否 否 否 否
Repeatable Read 否 否 是 否 否
Read Commited 否 否 是 是 是
Read Uncommited 否 是 是 是 是
在应用程序中如何使用乐观锁:
答:一般在数据库表中增加Version或者是TimeStamp字段,根据读取时以及在进行修改操作时Version或者TimeStamp的值不同来控制并发问题。
Hibernate是如何处理并发问题的:
答:
一、Hibernate在读取数据时通过设置锁定模式来控制悲观锁的形式
锁定模式 描述
LockMode.NONE 如果在Hibernate的缓存中存在指定对象,就直接返回该对象的引用;否则就通过Select语句到数据库中加载该对象。这是默认值
LockMode.Read 不管Hibernate的缓存中是否存在指定对象,总是通过select语句到数据库中加载该对象;如果映射文件中设置了版本元素,就执行版本检查,比较缓存中的指定对象是否和数据库中的版本一致。
LockMode.UPGRADE 不管Hibernate的缓存中是否存在指定对象,总是通过select语句到数据库中加载该对象;如果映射文件中设置了版本元素,就执行版本检查,比较缓存中的指定对象是否和数据库中的版本一致。如果数据库系统支持悲观锁就执行select。。。 for update语句,如果数据库系统不支持悲观锁,就执行普通的select语句。
LockMode.UPGRADE_NOWAIT 和LockMode.UPGRADE具有同样的功能。此外对于Oracle数据库,执行select。。 for update nowait语句。
LockMode.WRITE 当Hibernate向数据库保存或者更新一个对象时,会自动使用此模式。这种模式仅供Hibernate内部使用。
二、Hibernate在映射文件中使用乐观锁处理并发问题
1 、 < version > 元素:此元素指定的字段,每进行一次操作就自动加1,在进行读取和修改操作时如果version值不相同则抛出异常,交给应用程序处理。
2 、 < timestamp > 元素:此元素指定的字段数据,每进行一次操作就更新成当前时间。由于当前时间精确到妙所以在处理并发问题的精确性上没有 < version > 好。
注意:这两个元素在使用时都要紧跟在 < id > 元素后面。
3 、对于现有的数据库表不包含version或者timestamp字段,要处理并发问题可以在 < class > 元素上进行如下设置:
< class name = ”Account” table = ”Accounts” optimistic - lock = ”all” dynamic - update = ” true ” >
***************************************************************************************************************
作为Hibernate的创始人,Gavin King身上充满着传奇,坊间流传着很多关于他过往的“英雄”事迹,比如他在设计Hibernate时对SQL知识竟然一点儿也不懂,比如他对Spring创始人Rod Jonathan的“恶语相加”。在上周举行的Red Hat大会上,又听说Gavin在来北京的前两天因为骑摩托车速度太快,被摔成轻微脑震荡。不过所有的这些都不影响Gavin对技术的热忱和独立观点。
Oracle现在是Red Hat的铁杆竞争对手,推出自己的Linux操作系统,开源与Hibernate相竞争的ORM产品TopLink等。本以为请他评价此事会引爆Gavin的火爆脾气,他却大打太极拳:
这是件好事情,我举双手赞成。有很多原本不错的技术最后都因为没有竞争而死掉,ORM只所以现在还为人热捧,就是因为在这一领域里存在竞争。TopLink的开源会促进ORM技术的进步。
虽然Java EE 5已经改进了很多,但是远远没有达到人们的期望,尤其是在轻量级应用方面,于是有人说Java或者Java EE已死。Gavin King显然不同意这一观点:
与CORBA技术不同,它之所以现在已经淡出人们的视野,是因为很少有人在CORBA上继续下功夫,去关注它,改进它。Java则完全不同,它每月都在进步,去看看开源社区就知道了。很多项目都是基于Java而创建的,包括Hibernate,Java如果哪儿出了问题,会有很多人扑上去解决。能取代Java的技术还没有出现,不是C#,也不是Ruby。我的观点是Java的生命力还很强,会越来越棒,会继续发展下去。
对未来Java EE的发展,Gavin也抱有很多的期望,比如:
为无状态和有状态Session Bean提供更多的并发模式(Concurrecy Modes);
保证轻量级异步性(Lightweight Asynchronicity);
有状态Web服务端点(Stateful Web Service Endpoint);
……
答:
1 、当应用程序调用Transaction.Commit()方法的时候,先清理缓存,然后再向数据库提交事务。
2 、当应用程序调用Session.Find()或者Iterate()方法时,如果缓存中的持久化对象的属性发
生了变化,就会先清理缓存,以保证查询的结果能反映持久化对象的最新状态。
3 、当应用程序显式调用Session.Flush()方法的时候。
注意:Session进行清理缓存的例外情况是,如果对象使用native生成器来生成OID,那么当调用Session的Save()
方法保存该对象时,会立即执行向数据库插入该实体的insert语句
二、Session在清理缓存时,会按照什么顺序来执行Sql语句 ?
答:
1 、按照应用程序调用Session.Save()方法的先后顺序,执行所有对实体进行插入的insert语句。
2 、执行所有对实体进行更新的update语句。
3 、执行所有对集合进行删除的delete语句。
4 、执行所有对集合元素进行更新、删除、插入的sql语句。
5 、执行所有对集合进行插入的insert语句。
6 、按照应用程序调用Sesson.delete()方法的先后顺序,执行所有对实体进行删除的delete语句。
三、Session清理缓存的三种模式
清理缓存的模式 FlushMode.Auto FlushMode.Commit FlushMode.None
Session查询方法 清理 不清理 不清理
Session的Commit方法 清理 清理 不清理
Session的Flush方法 清理 清理 清理
四、Session的SaveOrUpdate方法如何工作,如何判断一个对象是临时对象还是游离对象 ?
答:如何传入的参数是临时对象就调用Save()方法;如果传入的对象是游离对象,就调用Update()方法;如果传入的参数是持久化对象就直接返回。
Hibernate判断临时对象的标准:
1 、 实体对象OID为null
2 、 实体对象具有version属性并且取值为null
3 、 在映射文件中为 < id > 元素设置了unsaved - value属性,并且OID取值与unsaved - value属性值匹配。
4 、 自定义Hibernate的Interceptor实现类,并且Interceptor的isUnsaved()方法返回Boolean.True。
五、在进行对象级联的时候有一个cascade属性,这个属性的属性值代表什么意义 ?
cascade属性值
描述
none
在保存、更新或者删除对象时,忽略其他关联的对象,它是级联的默认值
save - update
当通过Session的Save()、Update()以及SaveOrUpdate()方法来保存、更新对象时,级联保存关联的临时对象,并更新关联的游离对象。
delete
当通过Session的Delete()方法删除当前对象时,同时会删除关联的所有对象。
all
包含save - update以及delete的行为,此外对当前对象进行Evict()或者Lock()方法时会对关联的对象进行同样的操作。
delete - orphan
删除所有和当前对象解除关联关系的对象。
all - delete - orphan
包含all和delete - orphan的行为。
六、Hibernate在与触发器协同工作的时候如何保持数据的同步 ?
答:当Session执行Save()方法、SaveOrUpdate()方法、Update()方法时立即执行Session的Reflush()方法,直接绕过Session缓存从数据库中加载数据,
七、如何改变Hibernate操作持久化对象的行为 ?
答:通过对拦截器接口的实现改变Session的操作行为。
八. Hibernate缓存的种类 ?
答:分为内置缓存和外置缓存两种.
内置缓存的分类:
1 、Session中的内置缓存,这个是Hibernate缓存不可缺的组成部分,将持久化对象缓存到Session中
2 、SessionFactory中的内置缓存,这个是Hibernate缓存不可缺的组成部分,将一些数据库操作的
Sql语句缓存起来。这个缓存是只读的
持久化层的缓存的范围:
1 、事务范围:Session的内置缓存就是一个事务范围的,也就是缓存的生命周期随着事务的建立而产生,
随着事务的结束而消亡。
2 、进程范围:缓存被进程内的所有事务共享,这些事务由可能并发访问缓存,因此必须对进程范围的缓存
提供事务隔离机制。
3 、集群范围:缓存被同一个机器或多个机器上的多个进程共享。对于大多数应用要慎重考虑集群范围的缓存
由于并发的原因对应用性能影响较大。一般将只读的数据或者很少修改的数据存储到集群范围的缓存中。
外置缓存的支持:
Hibernate提供了EBCache、OSCache、SwarmCache、JBossCache这些第三方插件的适配器。具体的配置方法
请查看相关的文档。
注意:在对数据进行批量处理的时候为了提高性能还是直接通过Hibernate调用底层的数据库操作API。
数据库事务与并发
概述:事务通过隔离级别控制锁的形式来处理数据的并发问题。
九。为什么事务能够处理并发问题?
答:事务的特性决定它能够处理并发问题:一致性、隔离性、持久性、原子性
数据的并发有哪些情况?
答:
一、后发生的事务影响前面的事务
1 、第一类更新丢失:后发生的事务回滚覆盖了前面提交成功的事务
2 、脏读:后发生的事务成功提交覆盖了前面的回滚的事务
3 、第二类更新丢失:后发生的事务成功提交覆盖了前面的成功提交的事务
二、后发生的事务受到前面的事务的影响
1 、虚读:后一个事务在前后两次读取数据时由于前面的已提交的事务进行了插入操作,
而使数据统计前后不一致。
2 、不可重复读:后一个事务在对同一条数据前后两次读取时由于前面的已提交的事务
进行了对这条数据更新操作,而使数据前后不一致。
事务如何处理并发问题?
答:
事务通过锁来处理并发问题一般有两种方式:
悲观锁:通过数据库系统的锁来处理并发
乐观锁:通过应用程序逻辑处理并发
悲观锁的种类有哪些?
答:
一、共享锁:用于读数据操作。
特性:
1 、加锁条件:当一个事务执行select语句时数据库系统会为这个事务分配一把共享锁,来锁定被查询的记录。
2 、解锁条件:读取完毕则释放共享锁。
3 、兼容性:如果数据资源上已经放了共享锁还可放共享锁和更新锁。
4 、并发性能:具有良好的并发性能。
二、更新锁:在更新操作的初始化阶段用来锁定可能要被修改的资源,避免使用共享锁造成的死锁问题。
特性:
1 、加锁条件:当一个事务执行update语句时,数据库系统会先为事务分配一个更新锁。
2 、解锁条件:当读取数据完毕,进行更新操作时将更新锁升级为独占锁。
3 、兼容性:与共享锁兼容。一个数据资源上可以有多个共享锁和一个更新锁。
4 、允许多个事务同时读锁定的资源,但不允许其它事务修改它。
三、独占锁:修改数据时使用独占锁。
特性:
1 、加锁条件:当执行update、delete、insert操作时数据库系统会为数据资源使用独占锁。如果该资源上已经有其它锁
存在时则无法放置独占锁
2 、解锁条件:独占锁一直到事务结束才能被解除。
3 、兼容性:独占锁不能和其它锁兼容。
4 、并发性:并发性能较差。
事务如何控制锁的形式?
答:事务通过事务的隔离级别来控制锁的形式。
事务级别有哪些?并发情况怎样?
答:
隔离级别 是否出现第一类丢失更新 是否出现脏读 是否出现虚读 是否出现不可重复读 是否出现第二类丢失更新
Serializable 否 否 否 否 否
Repeatable Read 否 否 是 否 否
Read Commited 否 否 是 是 是
Read Uncommited 否 是 是 是 是
在应用程序中如何使用乐观锁:
答:一般在数据库表中增加Version或者是TimeStamp字段,根据读取时以及在进行修改操作时Version或者TimeStamp的值不同来控制并发问题。
Hibernate是如何处理并发问题的:
答:
一、Hibernate在读取数据时通过设置锁定模式来控制悲观锁的形式
锁定模式 描述
LockMode.NONE 如果在Hibernate的缓存中存在指定对象,就直接返回该对象的引用;否则就通过Select语句到数据库中加载该对象。这是默认值
LockMode.Read 不管Hibernate的缓存中是否存在指定对象,总是通过select语句到数据库中加载该对象;如果映射文件中设置了版本元素,就执行版本检查,比较缓存中的指定对象是否和数据库中的版本一致。
LockMode.UPGRADE 不管Hibernate的缓存中是否存在指定对象,总是通过select语句到数据库中加载该对象;如果映射文件中设置了版本元素,就执行版本检查,比较缓存中的指定对象是否和数据库中的版本一致。如果数据库系统支持悲观锁就执行select。。。 for update语句,如果数据库系统不支持悲观锁,就执行普通的select语句。
LockMode.UPGRADE_NOWAIT 和LockMode.UPGRADE具有同样的功能。此外对于Oracle数据库,执行select。。 for update nowait语句。
LockMode.WRITE 当Hibernate向数据库保存或者更新一个对象时,会自动使用此模式。这种模式仅供Hibernate内部使用。
二、Hibernate在映射文件中使用乐观锁处理并发问题
1 、 < version > 元素:此元素指定的字段,每进行一次操作就自动加1,在进行读取和修改操作时如果version值不相同则抛出异常,交给应用程序处理。
2 、 < timestamp > 元素:此元素指定的字段数据,每进行一次操作就更新成当前时间。由于当前时间精确到妙所以在处理并发问题的精确性上没有 < version > 好。
注意:这两个元素在使用时都要紧跟在 < id > 元素后面。
3 、对于现有的数据库表不包含version或者timestamp字段,要处理并发问题可以在 < class > 元素上进行如下设置:
< class name = ”Account” table = ”Accounts” optimistic - lock = ”all” dynamic - update = ” true ” >
***************************************************************************************************************
作为Hibernate的创始人,Gavin King身上充满着传奇,坊间流传着很多关于他过往的“英雄”事迹,比如他在设计Hibernate时对SQL知识竟然一点儿也不懂,比如他对Spring创始人Rod Jonathan的“恶语相加”。在上周举行的Red Hat大会上,又听说Gavin在来北京的前两天因为骑摩托车速度太快,被摔成轻微脑震荡。不过所有的这些都不影响Gavin对技术的热忱和独立观点。
Oracle现在是Red Hat的铁杆竞争对手,推出自己的Linux操作系统,开源与Hibernate相竞争的ORM产品TopLink等。本以为请他评价此事会引爆Gavin的火爆脾气,他却大打太极拳:
这是件好事情,我举双手赞成。有很多原本不错的技术最后都因为没有竞争而死掉,ORM只所以现在还为人热捧,就是因为在这一领域里存在竞争。TopLink的开源会促进ORM技术的进步。
虽然Java EE 5已经改进了很多,但是远远没有达到人们的期望,尤其是在轻量级应用方面,于是有人说Java或者Java EE已死。Gavin King显然不同意这一观点:
与CORBA技术不同,它之所以现在已经淡出人们的视野,是因为很少有人在CORBA上继续下功夫,去关注它,改进它。Java则完全不同,它每月都在进步,去看看开源社区就知道了。很多项目都是基于Java而创建的,包括Hibernate,Java如果哪儿出了问题,会有很多人扑上去解决。能取代Java的技术还没有出现,不是C#,也不是Ruby。我的观点是Java的生命力还很强,会越来越棒,会继续发展下去。
对未来Java EE的发展,Gavin也抱有很多的期望,比如:
为无状态和有状态Session Bean提供更多的并发模式(Concurrecy Modes);
保证轻量级异步性(Lightweight Asynchronicity);
有状态Web服务端点(Stateful Web Service Endpoint);
……