单独使用hibernate使用filter进行事务控制
public class HibernateSessionFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {
Session session = HibernateUtils.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
chain.doFilter(request, response);
tx.commit();
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
throw new RuntimeException(e);
} finally {
HibernateUtils.closeAndRemoveSession();
}
}
}
public class HibernateUtils {
private static Map<Thread, Session> sessionMap;
private static SessionFactory sessionFactory;
static {
sessionMap = new HashMap<Thread, Session>();
sessionFactory = new Configuration().configure().buildSessionFactory();
}
/**
* can only use in web filter, beause it should remove and clear resources
* @return
*/
public static Session openSession() {
System.out.println(Thread.currentThread().getStackTrace()[1] + " run in " + new Date());
Session session = sessionMap.get(Thread.currentThread());
if (session == null) {
session = sessionFactory.openSession();
sessionMap.put(Thread.currentThread(), session);
}
return session;
}
public static Session getCurrentSession() {
return sessionMap.get(Thread.currentThread());
}
public static void closeAndRemoveSession() {
System.out.println(Thread.currentThread().getStackTrace()[1]+ " run in " + new Date());//
Session session = sessionMap.remove(Thread.currentThread());
if (session != null) {
session.close();
}
}
}
hibernate整合进spring后的事务处理
1、声明式事务——使用tx标签配置的拦截器
<bean id="myHibTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<tx:advice id="txAdvice" transaction-manager="myHibTransactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="del*" propagation="REQUIRED" />
<tx:method name="do*" propagation="REQUIRED" />
<tx:method name="*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="bizMethods"
expression="execution(* com.voucher.service.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="bizMethods" />
</aop:config>
2、注解(待续...)
<!-- 定义事务管理器(声明式的事务) -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
此时在DAO上需加上@Transactional注解,如下:
@Transactional
public Users login(String uname, String upass) {
// TODO Auto-generated method stub
Users user=userDao.findByName(uname);
if(user!=null&&user.getUpwd().equals(upass)){
return user;
}
return null;
}
Hibernate getCurrentSession()的含义
getCurrentSession () 使用当前的session
openSession()重新建立一个新的session
在一个应用程序中,如果DAO 层使用Spring 的hibernate 模板,通过Spring 来控制session 的生命周期,则首选getCurrentSession ()。
1. 如果使用的是getCurrentSession来创建session的话,在commit后,session就自动被关闭了,
也就是不用再session.close()了。但是如果使用的是openSession方法创建的session的话,
那么必须显示的关闭session,也就是调用session.close()方法。这样commit后,session并没有关闭
2. getCurrentSession的使用可以参见hibernate\hibernate-3.2\doc\tutorial\src项目
3. 使用SessionFactory.getCurrentSession()需要在hibernate.cfg.xml中如下配置:
* 如果采用jdbc独立引用程序配置如下:
<property name="hibernate.current_session_context_class">thread</property>
* 如果采用了JTA事务配置如下
<property name="hibernate.current_session_context_class">jta</property>
Hibernate代码:
Session session = HibernateUnit.getSessionFactory().getCurrentSession();
session.beginTransaction();//getCurrentSession()要求事务
....
session.getTransaction().commit();
getcurrentSession()方法总是会返回“当前的”工作单元。
Session 在第一次被使用的时候,即第一次调用getCurrentSession()的时候,其生命周期就开始。然后她被Hibernate绑定到当前线程。当事物结束的时候,不管是提交还是回滚,Hibernate会自动把Session从当前线程剥离,并且关闭。若在次调用 getCurrentSession(),会得到一个新的Session,并且开始一个新的工作单元。这是Hibernate最广泛的thread- bound model,支持代码灵活分层(事物划分和数据访问代码的分离)。
使用hibernateTemplate.getSessionFactory().getCurrentSession(),使用的是hibernate的事务管理,而不是spring管理的事务是hibernateTemplate