简体   繁体   English

Java EE EJB作为可运行执行器

[英]Java EE EJB as Runnable executor

Is this code copmliant to Java EE spec and can be used? 该代码是否符合Java EE规范并且可以使用?

@Stateless
public class SomeBean {

    @Inject
    protected TransactedRunner txRunner;


    public void someFunc() {

        txRuner.run(new Runnable(){
            Connection c = ds.getConnection();
            //do jdbc stuff or jpa stuff
            //close everything etc.
        });
    }
}

@Stateless
public class TransactedRunner {

    @TransactionAttribute(REQUIRES_NEW)
    public void run(Runnable r) {
        r.run();
    }
}

In this case a new transaction should be started and every thing that will be done in runnable will be transacted. 在这种情况下,应该开始一个新的事务,并且将以可运行的方式完成所有操作。 Is that right? 那正确吗? Or there is some trick in which I should suffer from EE? 还是我应该遭受EE困扰?

There is an annotation in JavaEE6 called @Asynchronous which is specifically for this purpose. JavaEE6中有一个名为@Asynchronous的注释,专门用于此目的。 Here is the official tutorial: http://docs.oracle.com/javaee/6/tutorial/doc/gkkqg.html 这是官方教程: http : //docs.oracle.com/javaee/6/tutorial/doc/gkkqg.html

@Stateless
public class SomeBean {

    @Inject
    private SomeBean self;

    public void someFunc() {
        self.doSomething();
    }

    @TransactionAttribute(REQUIRES_NEW)
    @Asynchronous
    private void doSomething() {
        Connection c = ds.getConnection();
        //do jdbc stuff or jpa stuff
        //close everything etc.
    }
}

Also it's not allowed to create or manage Threads within a EJB Container. 另外,不允许在EJB容器内创建或管理线程。 Check out: http://www.oracle.com/technetwork/java/restrictions-142267.html#threads 检出: http : //www.oracle.com/technetwork/java/restrictions-142267.html#threads

Why is thread creation and management disallowed? 为什么不允许创建和管理线程?

The EJB specification assigns to the EJB container the responsibility for managing threads. EJB规范将管理线程的职责分配给EJB容器。 Allowing enterprise bean instances to create and manage threads would interfere with the container's ability to control its components' lifecycle. 允许企业bean实例创建和管理线程会干扰容器控制其组件生命周期的能力。 Thread management is not a business function, it is an implementation detail, and is typically complicated and platform-specific. 线程管理不是业务功能,它是实现细节,通常很复杂且特定于平台。 Letting the container manage threads relieves the enterprise bean developer of dealing with threading issues. 让容器管理线程可以减轻企业bean开发人员处理线程问题的负担。 Multithreaded applications are still possible, but control of multithreading is located in the container, not in the enterprise bean. 多线程应用程序仍然可以使用,但是多线程控制位于容器中,而不位于企业Bean中。

Method "run" will be executed in transaction, that's true. 方法“运行”将在事务中执行,这是正确的。 But it has nothing in common with threading or using executor. 但这与线程或使用执行程序没有共同之处。 In your example, the calling thread will execute your "run" method. 在您的示例中,调用线程将执行您的“运行”方法。 Runnable interface itself won't create a separate thread for you. 可运行接口本身不会为您创建单独的线程。

If you need this call to be executed by separate thread, you can use asynchronous calls, or, starting from EE7, a ManagedExecutorService is available: 如果需要通过单独的线程执行此调用,则可以使用异步调用,或者从EE7开始,可以使用ManagedExecutorService:

http://docs.oracle.com/javaee/7/api/javax/enterprise/concurrent/ManagedExecutorService.html http://docs.oracle.com/javaee/7/api/javax/enterprise/concurrent/ManagedExecutorService.html

This should work as intended. 这应该按预期工作。 But be aware, that multiple calls of txRunner.run during one service call might lead to inconsistent data if anything happens between or during those calls, like connection-timeout, transaction-timeout, or the node dies or something. 但是请注意,如果一次或两次服务调用之间或期间发生任何事情(例如连接超时,事务超时或节点死亡或其他原因),则一次服务调用中多次调用txRunner.run可能会导致数据不一致。 And the calling transaction (if there is any) might not see the changes done during the call until it itself has been committed. 并且,在提交之前,调用事务(如果有)可能看不到在调用过程中所做的更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM