什么是锁定我的有状态bean

时间:2018-02-02 08:36:01

标签: concurrency ejb lock-timeout

我在我的java EE应用程序中实现了一个断路器模式,因为它保持一个状态(多少次失败请求,平均响应时间,锁定/解锁等)我设置了inte {{1 }}。 并且为了避免由于容器锁定而导致序列化问题,我已添加@Stateful并确保所有操作都是线程安全的。

所以它目前看起来像这样:

@ConcurrencyManagement(ConcurrencyManagementType.BEAN)

但我还在。

@Stateful
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class CatalogBreaker extends Breaker {

但是如果我理解了所有内容,Caused by: javax.ejb.ConcurrentAccessTimeoutException: WFLYEJB0228: EJB 3.1 FR 4.3.14.1 concurrent access timeout on CatalogBreaker - could not obtain lock within 5000 MILLISECONDS 注释应该将锁定委托给bean而不是容器......并且因为CuncurrencyManagement没有任何锁或任何类型的锁,那么如何我收到这个错误了?

1 个答案:

答案 0 :(得分:0)

据我所知,有状态EJB总是被写锁所锁定,但是我很难找到任何说明这一点的正式Oracle文档(因此,语言:“据我所知”)。

换句话说,注释@ConcurrencyManagement(ConcurrencyManagementType.BEAN)不执行任何操作。对状态EJB的业务方法的同一实例的每次调用都将阻止下一个调用,从而不能同时执行状态EJB的两个业务方法。

如果您有多个线程尝试同时访问有状态EJB,则容器将阻止它们这样做,这说明您的性能下降。

默认情况下,超时为5秒,这在您的日志中也指示为默认值。您可以使用AccessTimeout来调整值,但是我相信大多数人都认为这样做是错误的做法。我认为大多数人都同意,如果您遇到超时问题,那么您需要重新考虑您的设计。默认值为5秒的原因是因为容器希望所有工作都是短暂的任务。您达到超时的原因不是因为您的工作花费太长时间,而是因为您使用的状态EJB与容器期望您使用它的方式不一致。并不是说从字面上看是错误的,就是不正确……有点像容器在爸爸的声音中说的:我不生气,只是失望。