当前位置: 首页 > 面试题库 >

JEE7:EJB和CDI bean是否支持容器管理的事务?

长孙兴德
2023-03-14
问题内容

Java EE7由一堆“ bean”定义组成:

  • 托管Beans 1.0(JSR-316 / JSR-250)
  • Java 1.0的依赖注入(JSR-330)
  • CDI 1.1(JSR-346)
  • JSF托管Beans 2.2(JSR-344)
  • EJB 3.2(JSR-345)

为了摆脱头脑中的混乱,我研究了几篇“何时使用哪种bean类型”的文章。 EJB 的优点之一似乎是 它们仅支持声明式容器管理的事务
(著名的事务注释)。不过,我不确定这是否正确。有人可以批准吗?

同时,我想出了一个简单的演示应用程序来检查这是否正确。我根据以下代码片段定义了一个CDI
bean( 不是 EJB-
它没有类级别的注释),如下所示:

public class CdiBean {
    @Resource
    TransactionSynchronizationRegistry tsr;

    @Transactional(Transactional.TxType.REQUIRED)
    public boolean isTransactional() {
        return tsr.getTransactionStatus() == Status.STATUS_ACTIVE;
    }
}

现在,在GlassFish 4.0上的结果是该方法实际上返回true,根据我的查询,该方法 未按预期工作 。我确实希望容器忽略CDI
bean方法上的@Transactional注释,甚至引发异常。我使用的是全新安装的GlassFish 4服务器,因此没有任何干扰。

所以我的问题是真的:

  • 哪些bean类型实际上支持容器管理的事务?
  • 只是出于好奇,如果上面的代码错误,我该如何用一个简单的演示应用程序对其进行测试?

(顺便说一句:有人描述了类似的问题,但其解决方案不适用于我的情况。


问题答案:

在Java EE 7之前,只有EJB是事务性的,并且@Transactional注释不存在。

从Java EE 7和JTA 1.2开始,您可以在带有@Transactional注释的CDI中使用事务拦截器。

要回答有关使用哪种最佳类型的bean的问题,答案默认为CDI。

CDI bean比EJB轻巧,并且支持许多功能(包括成为EJB),并且默认情况下处于激活状态(将beans.xml文件添加到应用程序时)。由于Java
EE 6
@Inject优先于@EJB。即使您使用远程EJB(CDI中不存在的功能),最佳实践也建议您@EJB一次注入远程EJB和CDI生产者以将其公开为CDI
bean

public class Resources {

    @EJB
    @Produces
    MyRemoteEJB ejb;

}

建议对Java EE资源也是如此

public class Resources2 {

    @PersistenceContext
    @Produces
    EntityManager em;

}

这些生产者将在以后使用

public class MyBean {

    @Inject
    MyRemoteEJB bean;

    @Inject
    EntityManager em;

}

EJB对于它们所包含的某些服务(如JMS或异步处理)仍然有意义,但是您将它们用作CDI bean。



 类似资料:
  • Java EE7由一系列“bean”定义组成: 托管bean 1.0(JSR-316/JSR-250) 为了摆脱脑海中的混乱,我研究了几篇“什么时候用哪种豆型”的文章。EJB的优点之一似乎是它们单独支持声明性容器管理的事务(著名的事务注释)。不过,我不确定这是否正确。有人能批准吗? 同时,我提出了一个简单的演示应用程序来检查这是否是真的。我刚刚根据这个片段定义了一个CDIBean(不是EJB-它没

  • 常见问题 服务协议

  • 问题内容: 我知道,现在大多数处理器都有两个或多个内核,因此多核编程非常流行。有在Java中利用此功能的功能吗?我知道Java有一个Thread类,但是我也知道这是在多核流行之前的很长时间了。如果我可以使用Java中的多个内核,我将使用什么类/技术? 问题答案: Java是否支持多核处理器/并行处理? 是。它还是其他编程语言的平台,在该平台上,实现增加了“真正的多线程”或“真正的线程”卖点。在较新

  • 我目前陷入以下情况: 我正在尝试将对象A保存到数据库中。但是A是由很多其他物体组成的,B,C,B,C由D,E组成...有很多嵌套的对象,你知道我的意思。让我们把保存A的整个过程称为事务1。 在事务1的中间,当涉及到保存一些对象X(它通过许多链接与A相关联)时,假设是方法SaveX()触发了保存X。在SaveX()方法中,业务逻辑要求对另一个对象Y进行另一个查询,假设方法是queryY()。 因此,

  • 我有一个应用程序,它有一个EJB,它注入了由CDI生成的实体管理器。同一服务器(wildfly 9)/JVM上的另一个应用程序将使用此EJB从实体管理器获取结果。 EJB的第一次调用将返回预期结果。当调用返回时,它生成实体管理器,获取数据并再次处理实体管理器。由于关闭了实体管理器,该EJB的每个后续调用都将抛出一个错误。未对新实体经理进行生产/处置。 这是预期的巴哈维奥吗?我的代码中有错误吗? 这