DeferredResult使休眠会话处于打开状态

时间:2019-07-16 14:16:57

标签: java spring jpa

我在http请求上使用spring DeferredResult。 控制器接收到一些信息,进行一两次查询,然后返回DeferredResult。

为简单起见,我在DeferredResult上设置了一个超时时间,然后等待它。

final RandomObj randomObj = someDAO.getSomething(someParameters);

final CustomResponse response = new CustomResponse();
response.setError("need_password");
return new DeferredResult<CustomResponse>(10L, response);

但是由于某种原因,超时到期后返回的超时后,Hibernate Session并未关闭。

在c3p0中,可以选择终止长时间未返回的连接并调试问题,在DeferredResult情况下,我总是在一段时间后得到此结果:

jul 16, 2019 10:42:26 AM com.mchange.v2.resourcepool.BasicResourcePool removeResource
INFO: A checked-out resource is overdue, and will be destroyed: com.mchange.v2.c3p0.impl.NewPooledConnection@13b130de
jul 16, 2019 10:42:26 AM com.mchange.v2.resourcepool.BasicResourcePool removeResource
INFO: Logging the stack trace by which the overdue resource was checked-out.
java.lang.Exception: DEBUG STACK TRACE: Overdue resource check-out stack trace.

我通过在Session.close()方法上放置一些断点来确认会话未关闭。

在其他端点中,一切正常,请求到来,会话打开,查询,会话关闭,请求完成。

EDIT1:

Seens spring-orm不会针对此类异步事件自动关闭会话:

https://github.com/spring-projects/spring-framework/blob/master/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewFilter.java#L162

EDIT2:

DAO代码: (只是将实体名称更改为Foo,其余相同)

@Repository
public class FooDAOImpl extends CustomHibernateDaoSupport {
    public Foo getByEmailAndAccountId(final String email, final Integer accountId, final Integer masterCompanyId) {
        final List<Foo> list = (List<Foo>) getHibernateTemplate().findByNamedQueryAndNamedParam("Foo.getByEmailAndAccountId",
                new String[] { "email", "accountId", "masterCompanyId" },
                new Object[] { email, accountId, masterCompanyId });
    }
}

EDIT3:

我认为我的问题是: Here已注册3个拦截器,您上面所说的AsyncRequestInterceptor是第二个。 执行超时触发器this代码后,  它首先触发this拦截器,此后,由于存在超时结果,因此它是assigned。 当迭代结束并且第二个拦截器(AsyncRequestInterceptor)将运行时,setOrExpired的结果(由于超时结果)为true,这会中断拦截器循环的执行。 因此,AsyncRequestInterceptor不会被标记为here,并且不会关闭会话 那是预期的行为?

0 个答案:

没有答案