Java EE EJB 作为 Runnable 执行器
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();
}
}
在这种情况下,应该启动一个新的事务,并且将在 runnable 中完成的每一件事都将被处理。那正确吗?或者有什么技巧让我患上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
Why is thread creation and management disallowed?
The EJB specification assigns to the EJB container the responsibility for managing threads. Allowing enterprise bean instances to create and manage threads would interfere with the container's ability to control its components' lifecycle. 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. Multithreaded applications are still possible, but control of multithreading is located in the container, not in the enterprise bean.
方法"run"会在事务中执行,没错。但它与线程或使用执行器没有任何共同之处。在您的示例中,调用线程将执行您的 "run" 方法。 Runnable 接口本身不会为您创建单独的线程。
如果您需要此调用由单独的线程执行,您可以使用异步调用,或者,从 EE7 开始,ManagedExecutorService 可用:
http://docs.oracle.com/javaee/7/api/javax/enterprise/concurrent/ManagedExecutorService.html
这应该可以正常工作。但请注意,如果在这些调用之间或期间发生任何事情,例如连接超时、事务超时或节点死亡等,在一个服务调用期间多次调用 txRunner.run 可能会导致数据不一致。并且调用事务(如果有的话)可能在调用期间看不到所做的更改,直到它本身被提交。
此代码是否符合 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?
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
Why is thread creation and management disallowed?
The EJB specification assigns to the EJB container the responsibility for managing threads. Allowing enterprise bean instances to create and manage threads would interfere with the container's ability to control its components' lifecycle. 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. Multithreaded applications are still possible, but control of multithreading is located in the container, not in the enterprise bean.
方法"run"会在事务中执行,没错。但它与线程或使用执行器没有任何共同之处。在您的示例中,调用线程将执行您的 "run" 方法。 Runnable 接口本身不会为您创建单独的线程。
如果您需要此调用由单独的线程执行,您可以使用异步调用,或者,从 EE7 开始,ManagedExecutorService 可用:
http://docs.oracle.com/javaee/7/api/javax/enterprise/concurrent/ManagedExecutorService.html
这应该可以正常工作。但请注意,如果在这些调用之间或期间发生任何事情,例如连接超时、事务超时或节点死亡等,在一个服务调用期间多次调用 txRunner.run 可能会导致数据不一致。并且调用事务(如果有的话)可能在调用期间看不到所做的更改,直到它本身被提交。