2

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

该方法仅使用注入的实体管理器并保留作为参数传入的实体。

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

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

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

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

4

2 回答 2

2

我设法在 Wildfly 10 上@Transactional使用CDI 和 CDI,但只有在设置为 class level时。在方法级别设置时它不起作用。@WebServlet@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");
   }
}

虽然仅注释该方法不起作用

   @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");
   }

我会调查的。

于 2018-01-06T20:01:33.900 回答
0

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

结论是@Transactional@WebServlet.

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

于 2018-01-03T19:34:21.067 回答