public class ExtOpenSessionInViewFilter extends OpenSessionInViewFilter{
    protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {     
        Session session = SessionFactoryUtils.getSession(sessionFactory, true);    
        this.setFlushMode(FlushMode.AUTO);
        /*FlushMode flushMode = getFlushMode();     
        if (flushMode != null) {     
            session.setFlushMode(flushMode);     
        }     */
        return session;     
    }
    
    protected void closeSession(Session session, SessionFactory sessionFactory){
        session.flush();
        super.closeSession(session, sessionFactory);
    } }改成public class ExtOpenSessionInViewFilter extends OpenSessionInViewFilter{
    protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {     
        Session session = SessionFactoryUtils.getSession(sessionFactory, true);   
        session.beginTransaction();
        this.setFlushMode(FlushMode.AUTO);
        /*FlushMode flushMode = getFlushMode();     
        if (flushMode != null) {     
            session.setFlushMode(flushMode);     
        }     */
        return session;     
    }
    
    protected void closeSession(Session session, SessionFactory sessionFactory){
        session.flush();
        session.getTransaction().commit();
        super.closeSession(session, sessionFactory);
    } }试试吧, 我感觉光flush不commit,要写进数据库的资源一直在JVM所托管的内存中,还得commit一下

解决方案 »

  1.   

    Spring原本建议使用OpenSessionInViewFilter时,事务是readOnly的,但你却一定要insert数据的话
    是必须事务提交的。
    既然已经改Spring类了,再改改也无所谓了:
    在方法,假设需要使用事务时,传递了一个参数叫isTransactionprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException{
           ...................
           String isTransaction = request.getParameter("isTransaction");
           if(StringUtils.isNotBlank(isTransaction)){
                session.beginTransaction();
           }
           ......................
           ........................}同理,关闭方法也根据这个参数来设置: protected void closeSession(Session session, SessionFactory sessionFactory, String isTransaction){
            session.flush();
             if(StringUtils.isNotBlank(isTransaction)){
                session.getTransaction().commit();
            }
            super.closeSession(session, sessionFactory);
        }  
    差不多了吧,不需要我再多说了吧。
      

  2.   

    没说非要readOnly啊。
    osiv允许里边带有嵌套事务。我觉得用老的osiv没啥问题,配合spring的support,没必要自己写什么commit的。
    当然,有时候需要flush还是要flush一下的。
      

  3.   

    再回一次吧:
    OpenSessionInViewFilter类的private FlushMode flushMode = FlushMode.NEVER; 默认设置是NEVER
    再回过来看Hibernate源代码:/**
     * The {@link Session} is never flushed unless {@link Session#flush}
     * is explicitly called by the application. This mode is very
     * efficient for read only transactions.
     *
     * @deprecated use {@link #MANUAL} instead.
     */
    public static final FlushMode NEVER = new FlushMode( 0, "NEVER" );
      

  4.   

    有怎么复杂吗只要使用spring挂上声明式事务就可以写了操作了,就这样,不建议你大改动.
      

  5.   

    kyo100900:
    不能每次有事务时我都传递一个参数吧?对于事务是不是会检查当前有没有需要处理的,如果没有事务也不会起什么作用?
      

  6.   

    楼主配置上声明事务就行了,spring这么有名的框架,不会随便搞个没有用的类让我们去二次修改的,既然很多人用,都没问题就说明你的用法不规范,我都用了快两年了也没什么问题,2个项目都这么干的.别把他搞复杂了,spring的意图就是simple