Java EE EJB作为Runnable执行程序

时间:2017-06-24 14:55:47

标签: java java-ee transactions ejb

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

在这种情况下,应该启动一个新事务,并且将在runnable中完成的所有事务都将被处理。是对的吗?或者有一些技巧我应该受到EE的影响?

3 个答案:

答案 0 :(得分:0)

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中。

答案 1 :(得分:0)

方法"运行"将在交易中执行,这是真的。但它与线程或使用执行程序没有任何共同之处。在您的示例中,调用线程将执行您的"运行"方法。 Runnable接口本身不会为您创建单独的线程。

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

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

答案 2 :(得分:0)

这应该按预期工作。但请注意,在一次服务调用期间多次调用txRunner.run可能会导致数据不一致,如果在这些调用之间或期间发生任何事情,例如连接超时,事务超时或节点死亡等。并且调用事务(如果有的话)可能看不到在调用期间完成的更改,直到它本身已经提交。