BANG老师: 请教一下Hibernate的session问题

我使用struts1.x + Hibernate3.X开发,不考虑用Spring

首先在Filter中创建和关闭session

public class HibernateFilter implements Filter {

//通过ThreadLocal来生成session
private static ThreadLocal hibernateHolder = new ThreadLocal();

//SessionFactory是--线程安全的
private static SessionFactory factory = null;

public void destroy() {

}

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
try {
//程序首先执行doFilter方法,继续向下传递,避免程序在此停住
chain.doFilter(request, response);
} finally {
//结束session的生命,程序运行结束必经地
Session session = (Session)hibernateHolder.get();
if(session != null) {
if(session.isOpen()) {
session.close();
}
//ThreadLocal也要remove
hibernateHolder.remove();
}
}
}

public void init(FilterConfig config) throws ServletException {
//filter在Tomat启动是只执行一次,在此创建SessionFactory是最好的
try {
Configuration cfg = new Configuration().configure();
factory = cfg.buildSessionFactory();
System.out.println("--------SessionFactory---------");
} catch (Exception e) {
e.printStackTrace();
}
}

//返回session,而session是由SessionFactory创建的,SessionFactory是重量级的
//最好只创建一次
public static Session getSession() {
//首先要判断当前的ThreadLocal中是否有Session的实例
Session session = (Session)hibernateHolder.get();
//有就取出,没有就创建并放入ThreadLocal中后返回实例
if(session == null) {
session = factory.openSession();
hibernateHolder.set(session);
}
return session;
}

}

然后,在通过ThreadLocal得到session(session = HibernateFilter.getSession();)

1.那么,假设有两个客户端,分别对同一数据进行都、写操作,会不会引起脏读?

2.如果并发访问大时,同一session中的事务增多,该如何解决?


[该贴被admin于2009-02-25 18:44修改过]

session放在threadlocal中,实际就将session的生命周期定义为request,一个客户端可以发出多个request,这是最短的生命周期。

脏读与事务有关,这个事务也是一般指request级别,所以,脏读是会正常发生,消灭脏读是和事务锁有关,以及HIbernate控制比如乐观锁或悲观所有关,具体看看ACID。

并发大时,每个请求占据事务时间长,当然影响性能,这是权衡平衡的,可通过引入可伸缩的架构来解决。