繁体   English   中英

Java EE EJB作为可运行执行器

[英]Java EE EJB as Runnable executor

该代码是否符合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();
    }
}

在这种情况下,应该开始一个新的事务,并且将以可运行的方式完成所有操作。 那正确吗? 还是我应该遭受EE困扰?

JavaEE6中有一个名为@Asynchronous的注释,专门用于此目的。 这是官方教程: 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.
    }
}

另外,不允许在EJB容器内创建或管理线程。 检出: http : //www.oracle.com/technetwork/java/restrictions-142267.html#threads

为什么不允许创建和管理线程?

EJB规范将管理线程的职责分配给EJB容器。 允许企业bean实例创建和管理线程会干扰容器控制其组件生命周期的能力。 线程管理不是业务功能,它是实现细节,通常很复杂且特定于平台。 让容器管理线程可以减轻企业bean开发人员处理线程问题的负担。 多线程应用程序仍然可以使用,但是多线程控制位于容器中,而不位于企业Bean中。

方法“运行”将在事务中执行,这是正确的。 但这与线程或使用执行程序没有共同之处。 在您的示例中,调用线程将执行您的“运行”方法。 可运行接口本身不会为您创建单独的线程。

如果需要通过单独的线程执行此调用,则可以使用异步调用,或者从EE7开始,可以使用ManagedExecutorService:

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

这应该按预期工作。 但是请注意,如果一次或两次服务调用之间或期间发生任何事情(例如连接超时,事务超时或节点死亡或其他原因),则一次服务调用中多次调用txRunner.run可能会导致数据不一致。 并且,在提交之前,调用事务(如果有)可能看不到在调用过程中所做的更改。

暂无
暂无

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

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