处理 EJB 中的 TransactionTimeout 异常
我有一个名为 methodA() 的 EJB 方法,它调用另一个名为 methodB() 的 EJB 方法,该方法启动一个新的容器管理事务。在方法B中,我强制事务超时,该超时被catchB正确捕获并且不会传播到方法A。但令我惊讶的是 methodA 收到了异常。我在这里错过了什么吗?
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 异常?
I have an EJB method called methodA() calling another EJB method called methodB() which starts a new container managed transaction. in methodB, I am forcing a transaction timeout which is rightly caught by caughtB and not propagated to methodA. But I am surprised that methodA receives the Exception. Am I missing soemthing here?
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..");
}
}
The first method should have never caught the exception (EJBTransactionTimeoutException) because the methodB have eaten it. I am seeing the output of "Shouldn't be here" instead of "print me!". It makes me wonder if container throws yet another exception of EJBTransactionTimeoutException immediately after methodB is completed although it has already thrown Timeout exception?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Thread.sleep()
永远不会抛出TransactionTimeoutException
,因此此 catch 块无法捕获此异常。当EJB A 从EJB B 调用methodB 时,它不会直接调用bean 方法。它在代理上调用 methodB。该代理负责处理事务管理、安全性等,然后调用 bean 实例上的实际 methodB。
因此,methodB 中不会抛出异常。它是从包装 EJB B 的代理调用的,当包装的 bean 实例的 methodB 返回并且执行时间超过配置的超时时,代理会抛出 TransactionTimeoutException。
Thread.sleep()
never throws aTransactionTimeoutException
, so there is no way this catch block catches this exception.When EJB A calls methodB from EJB B, it doesn't call the bean method directly. It calls methodB on a proxy. This proxy is responsible for handling the transaction management, the security, etc. and then call the actual methodB on your bean instance.
So the exception is not thrown from withing the methodB. It's called from the proxy which wraps the EJB B, and which throws a TransactionTimeoutException when methodB of the wrapped bean instance returns, and has taken more than the configured timeout to execute.