过滤器代码:
public class HibernateSessionFilter implements Filter{
 
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {
 
Session session = HibernateSessionUtil.openSession();
Transaction tx = null;

try {

tx = session.beginTransaction();
System.out.println("事物开始");
chain.doFilter(request, response);
System.out.println("事物结束");
tx.commit(); }catch (Exception e) {
System.out.println("回滚准备");
if(tx!=null){
 tx.rollback();// 异常,不会回滚
}
System.out.println("回滚结束");
throw new RuntimeException(e);
}finally{
System.out.println("关闭session");
HibernateSessionUtil.closeAndRemoveCurrentSession();
}
   } public void destroy() {
 
} public void init(FilterConfig filterConfig) throws ServletException {
 
}
}
使用的action:
public class InsertUserAction extends ActionSupport { @Override
public String execute() throws Exception { UserDao userdao = new UserDaoImpl(); userdao.save(new User());
int a = 1 / 0;//测试事物是否起作用
userdao.save(new User());
  return "success"; }
}
如果有需要我可以发工程,希望大家帮忙看看。(看的是传智播客的OA视频,他是sturts1,我的是struts2)

解决方案 »

  1.   

    LZ的过滤器和dao用了不同的session吧
      

  2.   

    lz你用request.getsession(),应该就不会有问题了
      

  3.   

    首先,我不知道楼主为什么想用filter来实现数据库操作的事务功能,个人觉得不是很好:
    一、若是原来代码已经不能修改了,
        1. 你的项目中如果集成了Spring,那Spring的声明式事务管理,不是更好的选择么,只需要在配置文件中配置一下就可以实现了,非常容易
        2. 如果没有集成Spring,从上面的代码,可以知道楼主的项目中持久化层使用了Hibernate,那么原代码中那些需要事务支持的功能代码,楼主应该已经为session开启了事务,如果没有开启,那说明楼主的原代码本身就有问题,一个有问题的代码,你这样去改,就没有什么意义了;若开启了,那原代码中你是openSession,还是getCurrentSession,filter中开启事务的那个session和你原码中的session是不是一个session,若是一个session,那么你的原码中需要事务支持的功能代码当操作完成的时候,肯定是已经提交了,那你再在filter中commit以及抛异常时rollback,还有什么用么;如果不是一个session,那你filter中开启事务的代码就更没有用了
    二、能改原码,重构你的模块代码,当然Spring的声明式事务管理是首选,如果不用Spring,一种方式是现在这样,filter中拦截到客户端的请求,openSession获取一个新的session,然后开启事务,你的代码中全部调用getCurrentSession来获取session,操作完成返回的时候在filter中统一commit,但是这样有一点不好的地方就是,用户的任何的需要访问数据库的请求都回开始一个事务,显然这并没有必要,那你可以采用采用第二种方式,使用ThreadLocal对象,里面存放开始了事务的session,不需要开始事务的直接从sessionFactory中获取就可以了,再设计一个公共的辅助工具类,e.g.:XxxUtils,事务的提交在filter中调用XxxUtils的方法对ThreadLocal中的session提交事务
    三、在Action中直接嵌入Dao个人觉得不是很好最后说一下5楼的回答,request.getSession()得到的session和hibernate中的session可不是一个东西,不要搞混了……以上只是我的个人建议,希望对楼主有用!
      

  4.   

    我是看传智播客的oa视频,是可以正确插入的,但是在 “int a = 1 / 0;//测试事物是否起作用” 这行发生异常,就不能实现事物的回滚了。
      

  5.   

    可以正常的插入,但是如果,int a = 1 / 0;//测试事物是否起作用
    这行发生异常就不能实现回滚了