【问题标题】:Is it possible to use TransactionManagementType.CONTAINER in a remote EJB?是否可以在远程 EJB 中使用 TransactionManagementType.CONTAINER?
【发布时间】:2017-11-30 07:04:23
【问题描述】:

是否可以在远程 EJB 实现中使用 TransactionManagementType.CONTAINER 而不是 TransactionManagementType.BEAN

为了进一步澄清,我不想在我的业务层中处理 beginroolback 方法,但我没有找到其他方法让它工作。

我正在使用 Glassfish 5 和 corbaname:iiop 协议来访问我的远程 EJB。

使用示例:

此代码块在我的服务器上运行:

package br.com;
@Remote
interface IRemote {void method();}

@Stateless
@TransactionManagement(value = TransactionManagementType.BEAN)
class Remote implements IRemote { 
@Resource
private UserTransaction ut;

void method(){
    try{
        ut.begin();
        <my business logic>
        ut.commit();
    }
    catch(Exception e){...}
}

这个代码块在我本地机器上的一个应用程序中运行:

@Stateless
class LocalBean {
    @EJB(mappedName = "corbaname:iiop:myserver.com:3700#java:global/RemoteApp/Remote!br.com.IRemote"
    private IRemote remote;
} 

我正在关注来自 Oracle 的 this tutorial,但它使用 TransactionManagementType.BEAN 没有任何解释。

有没有其他方法可以在不需要上述事务的情况下做到这一点?

【问题讨论】:

    标签: jakarta-ee transactions glassfish ejb corba


    【解决方案1】:

    查看容器管理的事务

    RequiresNew 属性 如果客户端在事务中运行 并调用企业 bean 的方法,容器获取 以下步骤:

    暂停客户的交易

    开始一个新事务

    委托方法调用

    方法完成后恢复客户端的事务

    如果客户端没有与事务关联,则容器 在运行该方法之前启动一个新事务。

    当你想确保 该方法始终在新事务中运行。

    https://docs.oracle.com/javaee/5/tutorial/doc/bncij.html

    【讨论】:

    • 当我使用任何@TransactionAttribute 时,我在部署时收到错误“方法级别的事务属性可能未在事务类型为 [Bean] 的 bean 上指定。有关详细信息,请参阅 server.log。”
    • 当我不使用@TransactionAttribute 时,当我执行持久操作时,运行时出现异常“TransactionRequiredException”
    • 事务属性只能在 CMT 中使用:参见docs.oracle.com/javaee/6/api/javax/ejb/…“TransactionAttribute 注释...只能在使用容器管理事务分界时指定。”
    【解决方案2】:

    默认情况下(来自 EJB 规范)会话 bean 使用 ContainerManagedTransaction 和Required 如果没有注释。 这应该可以远程或本地工作。

    你也可以直接做

    @TransactionManagement(value = TransactionManagementType.CONTAINER)
    @Required
    public class MyBean ... {
       @Supported  // override class level annotaion
       public void method(...) {
       }
    }
    

    从上面的错误消息中,我想你尝试使用 TMType.BEAN 但在方法中添加了一个 @Required 左右,这是被容器禁止的,因为不允许组合!

    【讨论】:

    • 当我使用@TransactionManagement(value = TransactionManagementType.CONTAINER)时,客户端出现异常:javax.ejb.EJBException: java.lang.SecurityException ... Caused by: java.lang.SecurityException at com.sun.jts.jta.TransactionManagerImpl.rollback(TransactionM‌​anagerImpl.java:376)
    • 关于@Required 和@Supported 我没有找到类...我使用maven 项目和&lt;dependency&gt; &lt;groupId&gt;javax&lt;/groupId&gt; &lt;artifactId&gt;javaee-api&lt;/artifactId&gt; &lt;version&gt;${javaee.api.version}&lt;/version&gt; &lt;scope&gt;provided&lt;/scope&gt; &lt;/dependency&gt;
    【解决方案3】:

    您需要从远程 bean 中完全删除 @TransactionManagement-Annotation,然后它默认为 CMT。使用UserTransaction 将是非法的。所以你也必须删除它,但这就是重点,不是吗?

    但请注意:您可能会创建远程事务,这意味着两个容器可能会使用 XA 协议进行同步。如果您不想这样,请将TransactionAttribute 定义为TransactionAttributeType.REQUIRES_NEW,然后您将拥有与以前相同的行为,而无需明确的用户事务。

    【讨论】:

    • 当我删除 @TransactionManagement 时,我在客户端出现异常:javax.ejb.EJBException: java.lang.SecurityException ... 原因:com.sun.jts 的 java.lang.SecurityException。 jta.TransactionManagerImpl.rollback(TransactionManagerImpl.java:376)
    • 我认为SecurityException与CMT无关,大概:see抓住它,或者解决它的原因。也许您可以显示完整的消息和堆栈跟踪
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    相关资源
    最近更新 更多