Java EE @ TransactionManagement.BEAN-它如何与容器管理的bean结合? [英] Java EE @TransactionManagement.BEAN - how does it combine with container managed beans?

查看:148
本文介绍了Java EE @ TransactionManagement.BEAN-它如何与容器管理的bean结合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在以下情况下,在callSessionBean2()中启动的事务将如何表现?暂停了吗?如果在SessionBean2中引发异常会怎样? SessionBean2设置为BEAN事务管理类型,因为它不与任何数据库通信,仅通过LDAP与AD服务器通信.

How will the transaction started in callSessionBean2() behave in the following scenario? Is it suspended? What happens if an exception is thrown in SessionBean2? SessionBean2 was setup with BEAN transaction management type because it does not communicate with any database, only with AD server via LDAP.

我之所以问是因为部署后几周,在生产服务器中出现问题,导致对SessionBean2的调用开始挂起,而事务超时是唯一的错误.我认为这种设置可能是一件坏事,任何人都可以阐明这一点吗?

I'm asking because I've been having issues in a production server some week after deployment that calls to SessionBean2 starts to hang, with transaction timeouts as the only error. I figured this setup might be a bad thing, can anyone shed light on this?

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class SessionBean1 {
    @Inject private SessionBean2 sessionBean2;

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void callSessionBean2(){
        sessionBean2.doThingsThatMightCauseException();
    }
}

@Singleton
@TransactionManagement(TransactionManagementType.BEAN)
public class SessionBean2 {
    public void doThingsThatMightCauseException(){...}
}

推荐答案

如EJB 3.1规范(第13.6.1节)中所述,调用方的事务将被挂起:

As declared in EJB 3.1 spec (§13.6.1), the caller's transaction will be suspended:

如果客户请求与交易T1相关联,并且 实例未与交易相关联,容器挂起 客户的交易关联,并使用 未指定的交易环境.容器恢复了客户的 事务关联(T1)时的方法(连同任何 相关的拦截器方法).

If the client request is associated with a transaction T1, and the instance is not associated with a transaction, the container suspends the client’s transaction association and invokes the method with an unspecified transaction context. The container resumes the client’s transaction association (T1) when the method (together with any associated interceptor methods) completes.

因此与SessionBean1关联的事务将被挂起,并且SessionBean2抛出的两种情况都将由调用bean处理,并带有适当的语义(即,由CMT会话处理)

So the transaction associated with SessionBean1 gets suspended, and the exceptions thrown by SessionBean2 in either case will be handled by the calling bean, with the appropriate semantics (i.e. treated by the CMT session)

您的代码是正确的,尽管我宁愿使用:

Your code is correct, though I'd rather use:

@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class SessionBean2 {
    public void doThingsThatMightCauseException(){...}
}

达到相同的效果.

您遇到的问题可能与@Singleton注释有关,该注释 根据§4.8.5.3和§4.8.5.3的规定,该Bean的默认值为:

The problem you are experiencing may be related to the @Singleton annotation, which according to §4.8.5.3 and §4.8.5.3 defaults the bean to be:

@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
@Lock(LockType.WRITE)

这会序列化doThingsThatMightCauseException的调用,从而导致随机的ConcurrentAccessTimeoutException.尽管可以通过@AccessTimeout配置并发访问超时,但如果(序列化的)doThingsThatMightCauseException访问延迟超过为CMT事务定义的超时,则会导致事务超时(请记住,与SessionBean1相关联的CMT事务被挂起,但时钟仍在计时...).

This serializes the invocations of doThingsThatMightCauseException, causing random ConcurrentAccessTimeoutException. Although the concurrent access timeout is configurable through @AccessTimeout, it will lead to a transaction timeout if the (serialized) doThingsThatMightCauseException access delay exceeds the timeout defined for CMT transactions (remember, the CMT transaction associated with SessionBean1 gets suspended, but the clock is still counting...).

包装:

您需要(请谨慎对待共享状态)使用以下命令更改doThingsThatMightCauseException上的访问锁定:

You need (with proper care to shared state) to change the access lock on doThingsThatMightCauseException with:

@Lock(LockType.READ)
public void doThingsThatMightCauseException(){...}

这将删除访问序列化,有望解决您的超时问题.

This will remove the access serialization, hopefully solving your timeout problems.

如果仍然遇到超时,则与doThingsThatMightCauseException中包含的操作缓慢有关. 在这种情况下,您将需要:

If you still experience timeouts, it will be related to the slowness of the operations included in doThingsThatMightCauseException. In this case you'll need to either:

  • 在任何事务之外调用该方法,
  • 或更改CMT交易超时(在AS特定的配置/部署中)
  • 或将SessionBean1转换为BMT,从而利用UserTransaction.setTransactionTimeout
  • call the method outside of any transaction,
  • or change the CMT transaction timeout (in the AS specific configuration/deployment)
  • or convert SessionBean1 to BMT, thus leveraging UserTransaction.setTransactionTimeout

这篇关于Java EE @ TransactionManagement.BEAN-它如何与容器管理的bean结合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆