【问题标题】:Does local call of an EJB abstract method open a new Transaction?EJB 抽象方法的本地调用是否会打开一个新事务?
【发布时间】:2017-06-24 20:10:05
【问题描述】:

假设类的构造如下:

一个Filereader 为文件找到匹配的导入器并调用Importer.import 方法。

此方法调用带有 REQUIRES_NEW 注释的抽象方法 importSpecific

从容器的角度来看,本地调用不会打开新的事务,但从继承的角度来看,我不确定。

ImporterBase.import 中的importSpecific 调用是否创建新事务?为什么会这样?

类 FileReader:

@Singleton(name = "FileReader")
public class FileReader extends Traceable {

    /*@Inject
      @Any
      public Instance<Importer> importers;*/

    @EJB
    ExampleImporter importer;

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void listenToFileAvailableEvent(@Observes FileAvailable event) throws InterruptedException {        
        for (final String filename : event.getFilenames()) {            
            readFile(filename);
        }
    }

    public void readFile(String filenameWithPath) {
        //[...]-> Extract FileMetadata and find correct importer
        importer.import(dateiMeta);
    }
}

接口导入器:

@Local
public interface Importer {
    void import(FileMetaData dateiMeta) throws Exception;
    void importSpecific(FileMetaData dateiMeta) throws Exception;
}

类 ImporterBase:

public abstract class ImporterBase implements Importer {
   @Resource
   private SessionContext ctx;

   @Override
   public void import(FileMetaData dateiMeta) throws Exception {           
       try {           
          ctx.getBusinessObject(Importer.class).importSpecific(dateiMeta);//This causes the error
       } catch (Exception ex) {            
           //[...] Log Error
           throw ex;
       }        
   }

   @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
   public abstract void importSpecific(FileMetaData dateiMeta) throws   Exception;

}

类 ExampleImporter:

@Stateless
public class ExampleImporter extends ImporterBase {

    @Override
    public void importSpecific(FileMetaData dateiMeta) throws Exception {
        //Import from file
    }   
}

【问题讨论】:

    标签: inheritance jakarta-ee transactions ejb


    【解决方案1】:

    不,importSpecific 何时(以及如何)被您的方法调用 import 永远不会打开新事务;因为(如您所说)对容器的调用始终是本地调用...

    但是根据this,注解@TransactionAttribute是可以继承的……所以,

    为了使这种配置发挥作用,您必须:

    1) 在你的业务接口声明importSpecific方法,也就是Importer接口。

    2) 将Importer 接口表示为您的本地接口。

    3) 在您的 FileReader Singleton 中,使用 @EJB 注释获取您的 Importer Bean 的代理。如果您使用 CDI 注释(如 @Inject),容器将注入 CDI 对象而不是 EJB 代理! (注意这个)

    4) 将您的 ImporterBase 代码更改为:

    public abstract class ImporterBase implements Importer {
        @Resource
        private SessionContext ejbCtxt;
    
        @Override
        public void import(FileMetaData dateiMeta) throws Exception {
            Importer proxy0;    
            try {           
                proxy0 = this.ejbCtxt.getBusinessObject(Importer.class);
                proxy0.importSpecific(dateiMeta);
    
            } catch (Exception ex) {            
                //[...] Log Error
                throw ex;
            }        
        }
    
        @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
        public abstract void importSpecific(FileMetaData dateiMeta) throws Exception;
    
    }
    

    5) 像这样更改您的ExampleImporter

    @Stateless
    @Local(Importer.class)
    public class ExampleImporter extends ImportBase {
    ...
    }
    

    如果您确实需要在 Singleton 类中使用 CDI Beans 而不是 EJB 代理,则需要使用 @Transactional CDI 注释来代替...并且您的代码也应该重构。

    【讨论】:

    • 感谢您的回复。我尝试了您的解决方案,但我总是得到一个 WFLYEJB0051:找不到视图 [...]EJB 的导入器 [...]ExampleImporter。我在界面上添加了'@Local'注解。
    • 我需要查看您的代码以便为您提供更多帮助...您可以用修改后的代码更新您的问题吗?
    • 对不起,回答迟了...我只是尝试您的代码,但您需要进行 2 处修改才能工作:一,将 ExampleImporter 类注释为:@Local(Importer.class) ...二,在FileReader Singleton,将您的EJB 声明为Importer 而不是ExampleImporter ... 示例:@EJB private Importer importer; 这有效.. 我刚刚尝试过
    • 感谢您的回复。我实际上有 10 个进口商,所以不仅仅是ExampleImporter。因此我有@Inject @Any Instance&lt;Importer&gt; importers。我怎样才能获得一个列表或与直接@EJB 相当的东西我必须写一个@Producer 吗?一个小例子会很棒!
    • 找到这个option
    猜你喜欢
    • 2010-09-30
    • 2014-12-11
    • 2021-12-21
    • 2021-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    相关资源
    最近更新 更多