当前位置: 首页 > 知识库问答 >
问题:

JEE7:EJB和CDIBean支持容器管理的事务吗?

章彬郁
2023-03-14

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

  • 托管bean 1.0(JSR-316/JSR-250)

为了摆脱脑海中的混乱,我研究了几篇“什么时候用哪种豆型”的文章。EJB的优点之一似乎是它们单独支持声明性容器管理的事务(著名的事务注释)。不过,我不确定这是否正确。有人能批准吗?

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

public class CdiBean {
    @Resource
    TransactionSynchronizationRegistry tsr;

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

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

所以我的问题是:

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

(BTW:有人在这里描述了一个类似的问题,但它的解决方案不适用于我的情况。

共有2个答案

程卓君
2023-03-14

Transactional的javadoc表示:

javax。交易事务性注释使应用程序能够在类和方法级别声明性地控制CDI托管bean上的事务边界,以及Java EE规范定义为托管bean的类,其中方法级别的注释覆盖类级别的注释。

所以,你的假设是错误的。在JavaEE6之前,EJB是唯一支持声明性事务的组件。JavaEE7中引入了事务性注释,以使非EJB、托管CDIBeans具有事务性。

满昊然
2023-03-14

在JavaEE7之前,只有EJB是事务性的,@transactional注释不存在。

由于JavaEE7和JTA1.2,您可以在CDI中使用带有@transactional注释的事务拦截器。

要回答您关于要使用的最佳bean类型的问题,默认情况下答案是CDI。

CDIBeans比EJB轻,支持很多特性(包括作为EJB),并且在默认情况下被激活(当您向应用程序添加beans.xml文件时)。因为JavaEE6@Inject取代了@EJB。即使您使用远程EJB(CDI中不存在的功能),最佳实践建议您一次@EJB注入远程EJB和CDI生产者,将其作为CDIBean公开

public class Resources {

    @EJB
    @Produces
    MyRemoteEJB ejb;

}

对于JavaEE资源,建议也是如此

public class Resources2 {

    @PersistenceContext
    @Produces
    EntityManager em;

}

这些生产者将在以后使用

public class MyBean {

    @Inject
    MyRemoteEJB bean;

    @Inject
    EntityManager em;

}

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

 类似资料:
  • 问题内容: 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 的优点之一似乎是 它们仅支持声明式容

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

  • 我们继续上一章节的内容,大家应该记得我们 Lua 代码中是如何完成 ngx_postgres 模块调用的。我们把他简单改造一下,让他更接近真实代码。 local json = require "cjson" function db_exec(sql_str) local res = ngx.location.capture('/postgres',

  • 《知晓云服务协议》是广州爱范儿科技股份有限公司及其关联公司(以下简称“本公司”、“本网站”或“甲方”)与所有使用知晓云服务的主体(包括但不限于个人、团队、企业等,以下简称“用户”、“您”或“乙方”)对知晓云服务及相关服务的使用所订立的有效合约。《知晓云服务协议》以下或简称“本服务协议”、“服务协议”或“本协议”。用户使用知晓云服务的任何行为即表示接受本协议的全部条款。本协议适用于任何知晓云服务,包

  • 常见问题 服务协议

  • 问题内容: 我正在使用Callable接口在serviceImpl中编写多线程程序。我正在使用spring事务管理器。在DB中执行更新操作时,它会成功执行。但是更新后的数据不会反映在DB中。但是,当我运行不带多线程的程序时,它将在DB中更新。 这是我的配置 我可以转向事务管理器的另一种方法。只是我想确认这种方法是否支持多线程。所以我的问题是 spring事务管理器是否支持多线程(我的意思是仅通过声