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

Spu*_*ick 19 java ejb jta java-ee cdi

Java EE7由一堆"bean"定义组成:

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

为了摆脱我心中的混乱,我研究了几篇"何时使用哪种豆类"的文章.EJB的一个优点似乎是它们单独支持声明性容器管理事务(着名的事务注释).不过,我不确定这是否正确.任何人都可以批准这个吗?

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

public class CdiBean {
    @Resource
    TransactionSynchronizationRegistry tsr;

    @Transactional(Transactional.TxType.REQUIRED)
    public boolean isTransactional() {
        return tsr.getTransactionStatus() == Status.STATUS_ACTIVE;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,GlassFish 4.0的结果是这个方法实际上返回true,根据我的询问,它没有按预期工作.我确实希望容器忽略CDI bean方法上的@Transactional注释,或者甚至抛出异常.我使用新安装的GlassFish 4服务器,因此没有干扰.

所以我的问题是:

  • 哪些bean类型实际上支持容器管理的事务?
  • 只是为了好奇,如果上面的代码错误,我怎么能用一个简单的演示应用程序来测试呢?

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

Ant*_*and 31

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

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

要回答有关要使用的最佳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;

}
Run Code Online (Sandbox Code Playgroud)

对于Java EE资源也建议使用相同的方法

public class Resources2 {

    @PersistenceContext
    @Produces
    EntityManager em;

}
Run Code Online (Sandbox Code Playgroud)

这些生产者将在以后使用

public class MyBean {

    @Inject
    MyRemoteEJB bean;

    @Inject
    EntityManager em;

}
Run Code Online (Sandbox Code Playgroud)

EJB继续对它们包含的某些服务(如JMS或异步处理)有意义,但您将它们用作CDI bean.

  • 不,因为默认情况下EJB是Transactional(约定优于配置方法)所以通常会得到特定的注释.此外,您可以使用EJB进行高级事务处理,例如嵌套事务或管理XA事务.但请记住,当您需要EJB时,它可以(并且应该)始终是CDI bean.是的,CDI可以替代轻型应用程序的EJB. (3认同)

JB *_*zet 7

Transactionaljavadoc说:

javax.transaction.Transactional注释为应用程序提供了声明性地控制CDI托管bean上的事务边界的能力,以及Java EE规范定义为托管bean的类,在类和方法级别,方法级别注释覆盖了班级.

所以,你的假设是错误的.直到Java EE 6,EJB才是支持声明式事务的唯一组件.事务性注释已经在Java EE 7中引入,以使非EJB,托管CDI bean具有事务性.