某公司关于spring和hibernate的面试题!高手来解答!!!!!!!

1
extends HibernateDaoSupport
for(int i=0;i<3;i++){
this.getHibernateTemplate().save(obj);
}
为什么只发出了一次insert语句 就保存了一个user?

2
getHibernateTemplate().save(obj);拿到的session是不是和当前线程绑定的?

3
关闭事务是HibernateTransactionManager是由这个类来关闭的,那么如果我没有配置
事务管理呢,由谁来关闭?
4


tx:attributes





/tx:attributes
/tx:advice
aop:config


/aop:config
在配置事务传播特性的时候我给com.common.service.*这个包进行事务管理,他里边有一些save..,update,delete啥的,也有些关于业务逻辑的接口,例如login。。。,那么我的这个login方法是不是不满足事务的描述 ,他的事务传播方式会走<tx:method
name="*" propagation="SUPPORTS" read-only="true" 对吗?这个包是service层,他们底层调用的都是同一个DAO现类extends HibernateDaoSupport,在这个类里边有CRUD,那么我在DAO层的save里边调用delete方法,在delete方法中我抛出一个runtimeexception 是不是就会事务回滚?因为他们都在同一个事务当中!?这些事务传播特性是指我调用service层时传播,还是说具体到实现类中,还是底层DAO中进行传播呢?
5
spring所谓的单例 是JVM的单例 还是说每个线程单例就像是ThreadLocal,
如果是jvm单例,那么是线程安全的吗?

6
struts2里边的ACTION是否是线程安全的,JVM单例还是每个线程绑定一个?

7
struts2假如每个线程一个ACTION,那么当用SPRING时,SPRING容器NEW出来的是单例(service层)【假如是JVM就存在一个service】,那么每个线程的ACTION调用service时会不会出现线程问题?该如何处理这个问题?

以上为题希望各位大牛给下解释,谢谢

10个回答

1 RE: 对于save方法,处理和saveOrUpdate相似,即处理过程如下:
1、obj创建以后,是瞬态对象;
2、第1个循环调用save以后,obj状态为持久态;
3、以后再对已持久化的对象调用save,和调用update作用一样,都被忽略。
所以只保存一个User。

2 RE:不一定。原因如下:
1、如果save操作发生时已打开事务,则拿到的session是和当前线程绑定的;
2、如果未打开事务,则分两种情况:
2.1、如果使用了OpenSessionInView模式,并且是默认设置(SingleSession=true),则拿到的session是和当前线程绑定的;
2.2、否则,拿到的是新session,并且不会绑定到当前线程。

3 RE:没有配置事务(或者说没有打开事务),何来关闭事务呢?
Spring下,如果没有打开事务,则使用JDBC自动提交事务,对数据库而言,每一条JDBC语句的执行都是一个事务。

4 RE:
1、例如login。。。,那么我的这个login方法是不是不满足事务的描述 ,他的事务传播方式会走 name="*" propagation="SUPPORTS" read-only="true" 对吗?
-------对的。
2、那么我在DAO层的save里边调用delete方法,在delete方法中我抛出一个runtimeexception 是不是就会事务回滚?
------DAO save方法也会被回滚,甚至到最外层的Sevice方法都会被回滚,因为事务的开启和回滚是围绕Service方法的。
3、这些事务传播特性是指我调用service层时传播,还是说具体到实现类中,还是底层DAO中进行传播呢?
------是指Service方法之间互相调用时的事务传播。
更具体的,是指不同类的Service方法互相调用之间的传播,同一个Service类之间的方法调用和事务传播没有关系,
原因很简单,Spring的事务管理是通过AOP(动态代理、或者字节码增强技术)来实现的,调用关系是:
外部类----->动态代理类------>被代理的Service类(只有经过动态代理类,事务管理或者事务传播才发生作用,
在Service类内部互相调用、Service调用DAO、DAO之间互相调用都和事务传播无关)

5 RE:默认情况下在容器内是唯一的。但好像也可以设置线程唯一、每请求唯一,具体记不清了。
如果是jvm单例,那么是线程安全的吗?
------这儿的线程安全,如果是指BeanFactory.getBean()的话,是线程安全的;
否则的话,具体的Bean对象是否线程安全和是否被Spring管理没关系。比如,通常情况下我们的Service都是单例的,
同时Service也设计成是无状态的,这种情况下Service就是线程安全的(因为它压根没有状态);
否则,如果Service有状态,并且这个状态是可变的话,那就不是线程安全的,设计中应避免这种情况。

6 RE:因为ACTION默认使用prototype,每次请求都会创建一个新的Action对象,所以,Action虽然不是线程安全的,但不会出现并发错误。
JVM单例还是每个线程绑定一个? -----严格说不是每线程绑定一个,应该是每请求绑定一个,
因为线程对象是在线程池中被重复使用的,在每次请求到来时,Struts2过滤器会把Action绑定到ThreadLocal,在请求结束时,把Action从当前线程剥离。

7 RE:当前不会出现问题。
Service之所以可以单例使用,就因为Service需要或者应该被设计成无状态的、也就是线程安全的。
线程安全也就是说可以被任意使用,不会有并发问题。

题外话,后面的几个题目(5/6/7)感觉不像是面试题,像是新手题目,因为问的太弱智了。。

1.不清楚你的问题在哪里,我只能说每调一次save方法就会插入一条数据;
2.用getHibernateTemplate后的session都是spring管理的,存在ThreadLocal里,当然和当前线程绑定;
3.没有配置事务就没有事务了,不过会执行jdbc自动事务提交,就是默认的每条sql语句都是一个事务;
4.事务传播举个例子:*.service.A类下有两个方法find() 和modify(),两个方法都配置了事务,其中modify()方法内部调用了find()方法,于是事务传播就在这里,find()就会加入modify()方法的事务里,是一个事务而不会是两个;
5.spring的单例是spring容器级别的单例,就是说每个ApplicationContext内的实例只有一个,如果你new了两个ApplicationContext,那就有两个容器,也就有两个实例,spring本身并不保证内部的bean是线程安全的,这个需要编程人员自己处理;
6.struts2的action就是被普通的POJO,谈不上线程安全,只不过默认struts2每个请求都会生成一个新的action实例,所以一般也不用考虑线程安全问题;
7.在spring bean配置时加上scope="prototype",就是每次获取时生成新的实例,这样就没有线程问题了,如果一定要用单例,但就要通过修改action bean代码,使其线程安全了。

不明白第一个问题什么意思。发一次当然值保存一个user了。

1.在hibernage 进行保存的时候他会检查该对象是否已经是数据库的值 如果已经是插入到数据库了,他是不会再进行插入操作的。
2.这个就要看你的session机制了 如果你的session不是使用Threadlocal形式,就谈不上。
3.不配的话没有事务不用管。
4.会回滚,事务传播是在servcie层。
5.spring的单例是容器级别的,当然他不是线程安全的。只是调用方法的话就谈不上什么安全不安全了。只要注意一下他的field就可以了
6.struts2里面的action每次请求就会创建一个,不用考利
7.不会存在问题 注意是你在调用service的时候里面不能使用成员变量。

第一个问题
我记得好像和数据的状态有关

obj对象在第一次被save之前是游离态,被save之后变成了持久态

hibernate在对持久态数据进行处理时会对数据(缓存优先)进行比对,

当发现数据未发生改变时,将不再和数据库进行交互

简单来说,save之后obj对象就有了id,

save带有id字段的对象是不行的

to fmjsjx
第二个问题好像是正确的,第三个问题请问可以找到源码在哪部分吗?第七个问题spring默认就是prototype

to tomorrowdesigner
spring默认的好像不是prototype吧

我还有一个问题,我在SPRING配置文件中没有写thread那么在DAO层,我用this.getHibernateTemplate().save(obj);是绑定当前线程的吗?

RE:
current_session_context_class 只是单独使用hibernate时才需要这样配置,
如果是通过Spring使用Hibernate的话,这个参数会被忽略,Spring会设置
自己的SpringSessionContext作为Hibernate的CurrentSessionContext的实现。

SpringSessionContext.currentSession()方法会调用:
SessionFactoryUtils.doGetSession(this.sessionFactory, false);

从而把session.currentSession()也和Spring管理的Session联系起来,
不过一般使用Spring的话,都是通过HibernateTemplate来获取Session,
HibernateTemplate也是通过SessionFactoryUtils来获取Session,
而SessionFactoryUtils获取Session时,首先检查的ThreadLocal上绑定的Session,
具体资源绑定在TransactionSynchronizationManager这个类中。
所以,不需要关注current_session_context_class 的设置。

我所有的action都要继承这个baseAction ,在这个Baseaction中有注入的service,那么我多个线程访问Action的时候,这些被注入的service是不是安全的,他们默认都是单例,当两个用户都访问同一个service的时候会出现问题吗?

RE:
这些被注入的service是不是安全的------是安全的
当两个用户都访问同一个service的时候会出现问题吗?----不会出问题。

你还没搞清线程安全的概念是怎么回事。

[quote]
问下第六个问题
@Scope("prototype")
public abstract class BaseAction extends ActionSupport implements ServletRequestAware, ServletResponseAware{
@Autowired
protected IUserManageService userManageService;
@Autowired
protected IRoleManageService roleManageService;
@Autowired
protected IActionManageService actionManageService;
@Autowired
protected IModuleManageService moduleManageService;
@Autowired
protected IMenuManageService menuManageService;

我所有的action都要继承这个baseAction ,在这个Baseaction中有注入的service,那么我多个线程访问Action的时候,这些被注入的service是不是安全的,他们默认都是单例,当两个用户都访问同一个service的时候会出现问题吗?
[/quote]
我之前已经说过了,spring容器里的bean其实就是个普通的java bean,spring本身并不关心其内容,也就是说spring并不保证你的service的线程安全,所有的线程安全问题都要你(程序员)自己处理,只要你service写得线程安全了,那就行了。
不过你这里的annotation @Scope("prototype")是不是起作用我不是很确定,记得类继承时好像是不会继承父类的class annotation的,这个你最好测一下。
至于之前的那什么spring配置的,我从来没配过这种东西,你DAO只要继承了HibernateDaoSupport并且都通过getHibernateTemplate()提供的方法访问数据库,那hibernate的session都会由spring来管理,放在一个ThreadLocal里,所以当然和线程绑定了。哦,说到这里,记得有个OpenSessionInViewFilter,保证session的生命周期,这个是一定要加的。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问