【问题标题】:java ee 7 @Transactional on a servlet methodjava ee 7 @Transactional 上的 servlet 方法
【发布时间】:2013-11-23 18:23:20
【问题描述】:

我有一个带有 webservlet 注释的 java ee 7 servlet。我已将 servlet 的方法之一标记为 @Transactional。实体管理器也提供给带有持久性上下文的 servlet。

该方法只使用注入的实体管理器并持久化作为参数传入的实体。

此方法在处理 http 请求时从 servlet 调用。 glassfish4 抛出一个异常,指出没有可用的事务。

我使用该方法定义了一个简单的托管 CDI bean,并在其上添加了 @Transactional 注释并注入了实体管理器。

我将该对象注入到 servlet 并从 servlet 调用该方法,一切正常。 em 被注入到 CDI bean,事务启动并且 em.persist 工作正常。

这是否意味着 servlet 对象的方法不能有 @Transactional 注释?

【问题讨论】:

  • 我不确定,可能是 servlet 无法代理。
  • 正确,或多或少。 Transactional 是为 CDI 和 EJB 使用而定义的。我认为它不适用于 Faces 托管 bean、Servlet 等。

标签: java cdi java-ee-7


【解决方案1】:

我在 TomEE plume 7.0.4 上试过这个。它不会抛出异常,但在我的测试中没有发生提交或回滚。

结论是@Transactional不适用于@WebServlet

编辑:在这些测试中,@Transactional 处于方法级别。它似乎在课堂上有效,请参阅@Rouliboy 的回答。

【讨论】:

  • 关于 javadoc The javax.transaction.Transactional annotation provides the application the ability to declaratively control transaction boundaries关于 CDI 托管 bean,以及由 Java EE 规范定义为托管 bean 的类。所以它应该在@WebServlet 上工作,因为它是一个托管bean。我会尝试一下wildfly和weblogic。
  • 相关:它也不适用于 TomEE 7 中的 JSF 托管 CDI bean。如果您看到不同的结果,请告诉我们。
  • 我在 Wildfly 上对其进行了测试,当 @Transactional 设置在类级别时它可以工作。在方法级别设置时不起作用。
【解决方案2】:

我设法使 @Transactional 在 Wildfly 10 上与 @WebServlet 和 CDI 一起工作,但仅当 @Transactional 设置在类级别时。在方法级别设置时不起作用。

所以下面的例子可以正常工作:

@Transactional
@WebServlet("/transactional")
public class TransactionalServlet extends HttpServlet
{
   /** The entity Manager */
   @Inject
   @AppStoreDatabase
   private EntityManager m_entityManager;

   @Override
   public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException
   {
      final Person person = new Person();
      person.setFirstName("FirstName");
      person.setLastName("LastName");

      m_entityManager.persist(person);

      response.getWriter().println("OK");
   }
}

虽然只对方法进行注释,但 NOT 起作用:

   @Transactional // Throws a TransactionRequiredException!
   @Override
   public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException
   {
      final Person person = new Person();
      person.setFirstName("FirstName");
      person.setLastName("LastName");

      m_entityManager.persist(person);

      response.getWriter().println("OK");
   }

我会调查的。

【讨论】:

  • 在 JSF 应用程序中使用会话范围的 CDI bean 与 TomEE plume 7.0.4 的结果相同。
猜你喜欢
  • 2013-08-01
  • 2016-01-13
  • 1970-01-01
  • 1970-01-01
  • 2013-06-25
  • 1970-01-01
  • 1970-01-01
  • 2015-12-19
相关资源
最近更新 更多