更新时间: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:
SessionBean1
转换为BMT,从而利用UserTransaction.setTransactionTimeout
SessionBean1
to BMT, thus leveraging UserTransaction.setTransactionTimeout