且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Java EE @ TransactionManagement.BEAN-它如何与容器管理的bean结合?

更新时间:2021-10-23 01:54:04

如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