将信息从 servlet 发送回过滤器

Sending information from a servlet back to a Filter

我在 Tomcat 7 上有一个旧的 Web 应用程序 运行,它使用过滤器提供的非常基本的打开会话视图机制:

@Override public void doFilter (ServletRequest req, ServletResponse resp, FilterChain fc) 
    throws IOException, ServletException 
{
    try {
        HibernateUtil.beginTransaction();
        fc.doFilter(req, resp);
        HibernateUtil.commitTransaction();
    } catch (Throwable t) {
        Logger.exception(t, "processing servlet request");
        HibernateUtil.rollbackTransaction();
        throw new ServletException(t);
    }
}

我现在受困于此,我认为我 运行 陷入了 OSIV(或至少是它的这个实现)的众多缺陷之一,我现在希望能够即使 没有 抛出异常也能回滚事务。我希望 servlet 能够控制它,而且我认为除了以某种方式破解此功能之外我没有太多选择。

我的问题是:如何将某种 "rollback" 标志从任意 servlet 传送回此过滤器?我希望能够在过滤器中做这样的事情:

HibernateUtil.beginTransaction();
fc.doFilter(req, resp);
if (/* something that was set by a servlet/jsp */)
    HibernateUtil.rollbackTransaction();
else
    HibernateUtil.commitTransaction();

我不太确定将类似信息从 servlet 传播回此过滤器的可靠方法是什么。

我不建议使用请求属性或线程局部变量,它们有以下问题:

  1. 您的交易取决于其他人设置的标志。如果你在银行工作,我真的不想成为那里的客户。
  2. 如果不清理线程本地存储,就会发生资源泄漏。
  3. 如果不在线程本地存储之间手动复制内容,就无法编写多线程代码。
  4. 如果使用请求属性,您必须提取 Servlet 中的值并一路传递给您的 DAO,假设您使用的是通用的多层架构。

相反,您可以简单地从 Hibernate 会话对象获取当前事务并要求它回滚。 Session.getTransaction().rollback()。最好废弃该代码或找到编写它的人并要求退款。