我的EJB3.1 bean初始化有困难,更具体地说,由于感知到的事务回滚而失败,即使我已经用@Transaction属性(NOT_SUPPORTED)
标记了bean。这应该意味着任何客户端事务都在bean方法条目上暂停,直到退出(当它将被恢复时。这绝对是我想要的事务apprach。
代码和错误的“要点”如下(注意,其中一些是手摇的,以隐藏细节,但都是相关的和有代表性的):
@Singleton(name = "MyClass")
@ConcurrencyManagement(value = BEAN)
@TransactionAttribute(value = NOT_SUPPORTED)
@Local(MyInterface.class)
public class MyClass implements MyInterface {
@PostConstruct
public void init() throws MyException {
try {
...
} catch LowerLevelException e) {
throw new MyException("problem", e);
}
}
public Object doSomething(...) throws MyException {
...
}
...
}
这会引发以下错误:
javax.ejb.NoSuchEJBException: Singleton MyClass(Application: my-ear, EJBComponent: my-ejb.jar) failed to initialize.
当我调试时,实际上包装了以下异常:
weblogic.ejb.container.InternalException: Transaction marked rollback or not expected transaction status: 4
同样,调试引发了一些有趣的细节:
MyClass#init
正在完全成功地执行,没有任何问题/异常。#init
在客户端代码首次调用我的#doSomething
方法时被调用(作为后构造的一部分)。MyClass#doSomething
的调用之间存在大量的堆栈间接级别,直到#init
并且异常会在这些层之一内引发。它在 WLS 单例会话 Bean 管理代码中引发。见下文...堆栈类似于下面(MyClass 名称已更改):
MyClass_fefgu8_Impl(MyClass).init() line: 96
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43
Method.invoke(Object, Object...) line: 601
Jsr250Metadata.invokeLifecycleMethod(Object, Method, Object[]) line: 393
InterceptionMetadata(Jsr250Metadata).invokeLifecycleMethods(Object, LifecycleEvent) line: 365
InterceptionMetadata.invokeLifecycleMethods(Object, LifecycleEvent) line: 403
EjbComponentCreatorImpl.invokePostConstruct(Object, String) line: 80
SingletonSessionManager.constructAndInitBean() line: 369
SingletonSessionManager.access$300(SingletonSessionManager) line: 63
SingletonSessionManager$SingletonLifecycleManager.doActualInit() line: 798 <== InternalException raised here
SingletonSessionManager$SingletonLifecycleManager.initInternal(boolean) line: 744
SingletonSessionManager$SingletonLifecycleManager.getBean() line: 648
SingletonSessionManager.getBeanFor(InvocationWrapper) line: 285
SingletonSessionManager.preInvoke(InvocationWrapper) line: 147
SingletonLocalObject(BaseLocalObject).getBeanInstance(InvocationWrapper) line: 146
SingletonLocalObject(BaseLocalObject).preInvoke(InvocationWrapper, ContextHandler, boolean, boolean) line: 103
SingletonLocalObject(BaseLocalObject).__WL_preInvoke(InvocationWrapper, ContextHandler) line: 67
SessionLocalMethodInvoker.invoke(Invokable, BaseLocalObject, InvocationWrapper, Object[], int) line: 20
MyClass_fefgu8_MyInterfaceImpl.doSomething(String, String, String, String) line: not available
事务回滚异常实际上是在堆栈帧中引发的:
SingletonSessionManager$SingletonLifecycleManager.doActualInit() line: 798
这个级别确实与事务管理器打交道,但我不知道为什么它应该尝试将事务标记为回滚,尤其是在从主应用程序代码成功初始化之后。
我使用这个EJB组件来编译这个bean,但我们在服务器上使用WLS EJB代码(或当然):
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.ejb</artifactId>
<version>3.1</version>
<scope>provided</scope>
</dependency>
我把它放在那里的原因是它被证明是棘手的,几乎没有在线的(特别是交易状态4),我在它上面花了太长时间,需要继续前进。我在继续寻找,但我想我可能会在周一回来时找到更多线索。
我已经重新阅读了很多关于EJB事务处理的内容,没有看到任何明显的问题。我相信我正在使用正确的机制来处理我的bean中的事务(即它是非事务的)。我还没有尝试将其放在描述符中(我刚刚想到并将尝试一下)。我也还没有深入研究单例SessionManager$SingletonLifecycleManager.doActualInit
的工作原理,但没有太多关于它的在线信息。
这个问题
换句话说,问题是…-我错过了什么,所以我的bean方法不参与任何提供的事务,或者更具体地说,不尝试将事务标记为回滚?-如果我明确告诉它不支持(关心)任何事务,为什么它应该无法初始化此错误?
注意:我已经检查过这个@Singleton bean未能初始化是因为意外的事务状态1问题,但是我的场景与Java EE安全角色权限无关(我不认为!)
谢了。
更新1
好吧,最新的是,删除我的@TransactionAttribute
注释似乎让我度过了失败。这很奇怪,因为默认值应该是 TransactionAttributeType#Required 并且确实,我们在堆栈跟踪中有一个额外的层,如果我调试太久,那么我的 bean init 中就会出现事务超时。
查看堆栈跟踪中的以下级别(慢慢nexting out),我看到有一个事务(实际上是两个):
SingletonSessionManager.constructAndInitBean() line: 377
wrap weblogic.ejb.container.internal.InvocationWrapper (id=15676)
L callerTx weblogic.transaction.internal.ServerTransactionImpl (id=15681)
L invokeTx weblogic.transaction.internal.ServerTransactionImpl (id=15683)
我将检查这些是否存在于预删除@TransactionAttribute
方案中,并尝试观看ServerTransactionImpl
。
更新 2
上次更新有一段时间了…不过,我想我已经将问题追踪到了SingletonSessionManager#postCallback
,它是从上面原始堆栈跟踪中的SingletonCessionManager#constructAndInitBean
调用的。(尽管如此,我需要确认这一点,因为我的潜在客户是通过运行事务案例来确定的)。如果/当我们试图回滚不存在的事务时,我们可能会失败。
N、 这不是一个最初的答案,只是一些更有用的信息,可以帮助我们深入了解这些问题的答案,因为这方面的在线信息并不多。经过进一步努力,原因和答案已经找到。答案保留了原来的格式,新的发现被记录为编辑和调试帮助,希望能够帮助其他有类似问题的人进行调试。这是一个黑暗的地方。
嗯,仍然没有明确的答案,上述问题和问题似乎已经消失了。
但是我发现(看另一个< code>NoSuchEJBException问题),潜在的原因被WLS堆栈所掩盖。
如果您没有将SingletonBean初始化到< code>PostConstruct方法中(例如,您的Bean无法创建),这是开始查找singleton bean未能初始化NosuchEJBException问题的合理位置:
SingletonSessionManager$SingletonLifecycleManager.doActualInit() line: 819
SingletonSessionManager$SingletonLifecycleManager.initInternal(boolean) line: 744
SingletonSessionManager$SingletonLifecycleManager.getBean() line: 648
SingletonSessionManager.getBeanFor(InvocationWrapper) line: 285
最初,根异常被捕获并包含在较低级别引发的< code>NoSuchEJBException中,如上所述。但是,在下面堆栈中的这一点上,< code>NoSuchEJBException被替换为< code>InternalError,该错误被包装,原因丢失。奇怪的是,它甚至可能将自己设置为原因(调试器有点失控):
SingletonSessionManager#getBeanFor
因此,这是查找根异常的最佳位置。
仅供参考:我在第二个实例中的问题是 WLS(Spring重新打包)中的Spring注入问题,其中数据源没有正确注入我的 ELB 服务 impl,因为数据源不存在@Resource(name=“...”)
JNDI 名称。由于上述异常处理问题,根本没有记录此情况。一旦我踏入并找到原因,它就很容易解决。不得不花这么多时间找出它,真是太可惜了。
[编辑]仅供参考:似乎我引起“InternalExc的Transact Rolled-back状态4”异常的问题可能是由于EJB初始化(PostCon结构体)超过了事务超时。如果我的EJB设置为@TransactionAt的属性(NOT-SUPPORTED)
,这应该是无关紧要的,但显然不是这样。调试显示,对于这个和@TransactionAt的属性(NEVER)
,有一个在
的级别上使用了一个
调用Tx
,并在中进行了管理。因此,超时会导致回滚,导致
InternalExc的
,映射到NoSuchEJBExc的
,吞并了其他NoSuchEJBExc的
导致垃圾错误消息。
[编辑2]仅供参考:这似乎是由于 WLS 中的一个错误,其中在不应该用于
@Transacthtml" target="_blank">ionAttribute(不支持)
时设置和管理 invokeTx。我们已经向Oracle提出了一个错误,他们给了它一个sev 2。同时,作为解决方法,我们已将可能耗时(依赖于网络)的代码从 @PostConstruct
方法中移出。
[编辑3]仅供参考:来自甲骨文...类级事务属性注释不会在单例生命周期拦截器后构造/预销毁上强制执行,因此它默认为 REQUIRED。
他们同意这是一个问题,并正在调查它。同时,请确保
@PostConstruct
中的代码不会违反事务超时。这将包括基于延迟的超时(我们的问题是间歇性的,因为它取决于访问的地理“服务器”)。
调试提示
作为一个调试过程,顺便说一句,我想我会:
在 EJB init (@PostConstruct
) 方法中放置一个断点并展开,直到看到调试值中出现异常。
- 如果您没有命中 init,请将断点尽可能靠近上面列出的 WLS
#doActualInit
,并找到进入 init 方法的方法。 然后,只需注意首次引发异常的时间。请注意,您可能必须将断点放在 InvocationHandler#invoke
中,才能通过代理层(或滚动自己的)接近这一点。 - 如果你确实击中了它,通过在
init
中放置一个断点来观察展开堆栈,或者在EjbComponentCreatorImpl.invokePostConstruct(Object,String)
中放置一个断点并观察。
我有一个场景,我需要在应用程序启动时加载一个 bean (ReportManager),以便它可以安排报告执行(由 DataStore bean 从数据库轮询)。 在谷歌上搜索后,我发现了@单件、@启动和@依赖的注释,我是这样使用的: 问题是我在部署期间遇到了非常奇怪的异常: 不是真正的异常消息。特别是我也没有收到任何“初始化”日志条目。当我注释掉dataStore.getReports()调用时
在Kotlin中,如果变量在应用程序启动时为,并且在创建后不能再次赋值为,那么有什么方法可以对其进行注释吗? 我不能将field设置为例如,因为它可以在某个时候被置为空,或者,因为它在使用之前被初始化(或者这可能是解决我的情况的正确方法?)。
我使用初始化Spring bean中的类属性。现在我看到这个任务可以通过Java内置的静态和非静态初始化器来完成。如何使用而不能使用初始化器块?
如果我在我的类中创建一个bool,就像一样,它默认为false。 当我在我的方法中创建相同的bool时,我得到一个错误“使用未分配的局部变量检查”。为什么?
下面的示例类无法编译: 此代码的编译错误消息是: 但是,对于包含以下方法的类,Java不会生成任何错误消息: 关于初始化及其要求,为什么Java对最终实例变量和最终局部变量的处理不同?谢谢
我正在使用React-useState创建状态为的对象。在成功调用API后,将更新为数据对象。 我有一个表单可以更改此状态,但我还有一个取消按钮。单击“取消”时,如何将此状态恢复为其初始值(API调用后)? 我应该创建另一个状态变量和存储初始状态在那里,然后更新我的状态基于?