hibernate transaction begin/rollback/commit vs. also session.clear()

时间:2016-04-04 18:07:13

标签: java sql database hibernate transactions

I am handling some old application code, and there seems to be several concepts involved, so I am looking to make sure I can improve them into one solid and strict practice.

Basically, the whole code is wrapped with a HibernateSessionRequestFilter like this

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    try {
        sf.getCurrentSession().beginTransaction();            

        chain.doFilter(request, response);

        sf.getCurrentSession().clear();

    } catch (...) {        
        //...
    } finally {
        sf.getCurrentSession().close();
    }

}

Then, there is an interceptor, doing something like this

private String loadStaff(...) {
    //...

    try {
        dbSession = //...;
        dbSession.beginTransaction();

        // some logic

        dbSession.getTransaction().rollback();

    } catch (RuntimeException e) {
        //..
    }
    finally {
        if (dbSession != null && dbSession.isOpen()) {
            dbSession.clear();
        }
    }
    }

And then there is even more business logic code with some more begintransactions and session clear etc.

So, questions:

  1. What happens when beginTransaction called more than once on same session?
  2. Sometimes, calling "clear()" throws exception, I think it happens after a "rollback()" was called. How to fix that?
  3. In general, what is the best proposed practice to combine session.clear() with transaction begin/rollback/commit ?

Thank you

1 个答案:

答案 0 :(得分:0)

您的代码应如下所示,这是处理单个http请求的事务的方法,

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    try {
        // Open the transaction.
        sf.getCurrentSession().beginTransaction();            

        // Handle the request
        chain.doFilter(request, response);

        // Persist the db changes into database.
        sf.getCurrentSession().commit();

    } catch (...) {        
        // Somthing gone wrong while handling the http request so we should remove all the changes and rollback the changes that are done in the current request.
        sf.getCurrentSession().rollback()
    } finally {
        sf.getCurrentSession().close();
    }

}

在代码的其他部分不应该处理begintransaction / close / commit事务。它应该只在一个地方处理。