事务性 @observes 是否适用于 JBoss AS 7 上的触发事件?
为了使用仅在事务成功或失败时侦听的事件,我遵循有关事务观察者的给定文档: http://docs.jboss.org/ weld/reference/1.1.0.Final/en-US/html_single/#d0e4075
...但无法使我的代码在 JBoss AS7 上运行。
这是我的 EJB:
@LocalBean
@Stateful
@TransactionAttribute(TransactionAttributeType.NEVER)
public class MyController
{
@Inject
private transient Event<MyEvent> myEventLauncher;
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void save()
{
myEventLauncher.fire(new MyEvent());
}
@AfterCompletion
protected void afterSave(boolean isCommitted)
{
// do stuff
}
}
这是我的基本侦听器:
public class MyHandler
{
protected void listenMyEvent(@Observes(during=TransactionPhase.AFTER_SUCCESS) MyEvent event)
{
// do stuff
}
protected void listenMyEvent2(@Observes(during=TransactionPhase.AFTER_FAILURE) MyEvent event)
{
// do stuff
}
}
当事件被触发时,我可以说我处于事务中,因为调用了 EJB 的 afterSave
方法。唉,方法 listenMyEvent
和 listenMyEvent2
总是被同时调用,就像我不在事务上下文中一样。
我在 GlassFish 3 上尝试了相同的代码,它完美地工作,所以我猜测 JBoss AS 7 有问题,但我找不到任何关于它的错误报告。
In order to use events only listened if a transaction succeeds or fails, I'm following the given doc about transactional observers :
http://docs.jboss.org/weld/reference/1.1.0.Final/en-US/html_single/#d0e4075
... but cannot manage to make my code work on JBoss AS7.
Here's my EJB:
@LocalBean
@Stateful
@TransactionAttribute(TransactionAttributeType.NEVER)
public class MyController
{
@Inject
private transient Event<MyEvent> myEventLauncher;
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void save()
{
myEventLauncher.fire(new MyEvent());
}
@AfterCompletion
protected void afterSave(boolean isCommitted)
{
// do stuff
}
}
And here my basic listener:
public class MyHandler
{
protected void listenMyEvent(@Observes(during=TransactionPhase.AFTER_SUCCESS) MyEvent event)
{
// do stuff
}
protected void listenMyEvent2(@Observes(during=TransactionPhase.AFTER_FAILURE) MyEvent event)
{
// do stuff
}
}
I can say I'm in a transaction when the event is fired, because the afterSave
method of the EJB is called. Alas, the methods listenMyEvent
and listenMyEvent2
are always called both, like if I was not in a transactional context.
I tried the same code on GlassFish 3 and it perfectly works, so I guess there is a problem with JBoss AS 7, but I cannot find any bug report about it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好吧,由于我当前的测试让我认为事务观察者在 JBoss AS 7 中不起作用,所以我设法为感兴趣的人提供了一个解决方法。
首先,我们需要限定符注释:
Immediate
、AfterFailure
和AfterSuccess
。此外,还可以在运行时创建这三个注释的三个基本
AnnotationLiteral
实例。然后,我们需要一个用于真实事件的封装器,我将其命名为
SpecialEvent
。最后,这个特殊事件的观察者和您想要触发此类事件的类的拦截器(下面有完整的解释)。
机制非常简单:
SpecialEvent
。SpecialEventObserver
将捕获任何SpecialEvent
并立即使用Immediate
限定符触发您自己的事件。它还会将完成后部分的事件排队。ic.proceed
),MyInterceptor
将要求SpecialEventObserver
再次触发所有事件AfterFailure
限定符或AfterSuccess
限定符,具体取决于您的方法是否成功。@Observes(during=...)
,例如@Observes @Immediate
、@Observes @AfterFailure
或@Observes @AfterSuccess
。该行为并不完全是提供本机
@Observes(during=...)
的行为。完成后部分不是基于事务状态,而是基于您自己的方法调用成功:IN_PROGRESS
就可以了。Well, as my current tests made me think that transactional observers are not working in JBoss AS 7, I managed to do a workaround I gave here for people who are interested.
First, we need qualifier annotations:
Immediate
,AfterFailure
andAfterSuccess
.Also, three basic
AnnotationLiteral
to create in runtime instances of this three annotations.Then, we need a encapsulator for our true events, that I named
SpecialEvent
.And at last, an observer for this special event and an interceptor for classes where you want to fire this kind of events (full explanation below).
The mechanism is quite simple:
SpecialEvent
that hold the true event.SpecialEventObserver
will catch anySpecialEvent
and will immediately fire your own event with anImmediate
qualifier. It will also queue the events for the after completion part.ic.proceed
in the interceptor),MyInterceptor
will ask theSpecialEventObserver
either to fire again all events with aAfterFailure
qualifier or aAfterSuccess
qualifier, depending of the success of your method.@Observes(during=...)
, your own observers have to observe events with the right qualifier, like@Observes @Immediate
,@Observes @AfterFailure
or@Observes @AfterSuccess
.The behavior is not exactly the one that provides the native
@Observes(during=...)
. The after completion part is not based on the transaction state, but on your own method call success:IN_PROGRESS
would do.这适用于版本 7.1.0.Final,据说(-> 与 Jboss 你永远不知道)完全兼容 Java EE。此外,您的 bean 不是线程安全的,因为它使用列表而不是并发队列。
This works with version 7.1.0.Final which is supposedly (-> with Jboss you never know) fully Java EE compliant. Also your bean is not thread-safe as it uses list instead of a concurrent queue.
您的观察者方法需要 REQUIRES_NEW,如下所述:
http://www.seamframework.org/Documentation/WhyIsThereNoActiveTransactionInMySFSBTransactionalObserver
Your observer methods need REQUIRES_NEW, as stated here :
http://www.seamframework.org/Documentation/WhyIsThereNoActiveTransactionInMySFSBTransactionalObserver