我有一个名为methodA()的EJB方法调用另一个名为methodB()的EJB方法,该方法启动一个新的容器管理事务。在methodB中,我强制一个事务超时,它被catchB正确捕获并且没有传播给methodA。但是我很惊讶methodA收到了Exception。我在这里错过了什么吗?
methodA() {
try {
methodB();
System.out.println("print me!");
} catch(Exception e) {
System.out.println("shouldn't be here");
}
}
@TransactionTimeout(5) //5 sec timeout
methodB() {
try {
Thread.sleep(6000);
} catch(Throwable t) {
System.out.println("Eating all the Exception..");
}
}
第一个方法应该从未捕获过异常(EJBTransactionTimeoutException),因为methodB已经吃过它。我看到“不应该在这里”而不是“打印我!”的输出。它让我想知道,尽管已经抛出了Timeout异常,容器会在methodB完成后立即抛出另一个EJBTransactionTimeoutException异常吗?
答案 0 :(得分:5)
Thread.sleep()
从不抛出TransactionTimeoutException
,因此此catch块无法捕获此异常。
当EJB A从EJB B调用methodB时,它不会直接调用bean方法。它在代理上调用methodB。该代理负责处理事务管理,安全性等,然后在bean实例上调用实际的methodB。
因此不会因为使用methodB而引发异常。它从包装EJB B的代理调用,并在包装的bean实例的methodB返回时抛出TransactionTimeoutException,并且执行的配置超时时间超过配置的超时。