在以下设置中,方法B是否在(新)事务中运行?
EJB,有两种方法,方法A和方法B.
public class MyEJB implements SessionBean public void methodA() { doImportantStuff(); methodB(); doMoreImportantStuff(); } public void methodB() { doDatabaseThing(); } }
EJB是容器管理的,require_new事务中的methodB和所需事务中的方法A. 从而:
MyName * Required MyName methodB RequiresNew
现在让另一个EJB调用方法A与EJB方法调用.methodA现在在一个事务中运行.从methodA对methodB的后续调用是在同一个事务中运行,还是在新事务中运行?(记住,这是实际的代码.没有明确的ejb调用方法B)
您的调用methodB()
是对方法的普通调用,不是由EJB容器拦截的; 在运行时,EJB容器将注入代理而不是类的实例,这是它在调用方法之前拦截调用和设置环境的方式.如果您使用this
直接调用方法而不是通过代理调用方法.因此,无论ejb-jar.xml中通过EJB接口进行调用的内容如何,两种方法都将使用相同的事务.
注入SessionContext,并询问它是否为您的代理实例:
@Stateless public class UserFacade implements UserFacadeLocal { @Resource private SessionContext context; @Override @TransactionAttribute(TransactionAttributeType.REQUIRED) private void create(User user) { System.out.println("Users Count: "+count()); //invocation#1 System.out.println("Users Count Through Context: "+context.getBusinessObject(UserFacadeLocal.class).count()); //invocation#2 } @Override @TransactionAttribute(TransactionAttributeType.NEVER) public int count() { return ((Long) q.getSingleResult()).intValue(); } }
在"调用#1"中,这是一个本地调用,不通过代理,它将返回计数
在'invocation#2'中,这是一个通过代理的调用,因此你注释它不支持事务 - 现在由create(user)方法打开 - 这个调用将抛出一个事务异常:
javax.ejb.EJBException:无法在全局事务中调用EJB