【问题标题】:How stateless beans deal with singleton ones?无状态 bean 如何处理单例bean?
【发布时间】:2017-08-31 16:59:08
【问题描述】:

当我有一个使用单例 JPA DAO 的无状态服务类并且许多客户端同时请求相同的方法时,EJB 是否会堆积剩余的请求?等待是否有时间/请求列表大小限制?它是否知道一次只有一个无状态者可以访问 DAO?如果是,它是如何做到的?

我认为如果发出 100 个请求,则实例化 100 个无状态 bean,但只有一个 DAO 实例。这会引发异常还是会发生某种管理?拥有 DAO 确实会使无状态服务池变得无用吗?

最后,什么是正确行为所必需的,我的意思是,无状态 bean 排队等待单例 DAO 的片刻?

【问题讨论】:

  • 为什么 DAO 是单例的?将其设为@Stateless 也是正常的。然后瓶颈将成为连接池的大小。
  • 我将 DAO 设计为单例只是因为第一次在教程操作上看到 JPA EJB DAO 实现也是这样做的。从那以后我开始思考这个问题,这些答案让我确定我不会再遵循这种模式了

标签: jakarta-ee ejb


【解决方案1】:

Singleton 的访问由EJB 容器同步。查看关于并发管理的documentation 部分。这来自文档:

单例会话 bean 是为并发访问而设计的,在这种情况下,许多客户端需要同时访问会话 bean 的单个实例。单例的客户端只需引用单例即可调用单例公开的任何业务方法,而无需担心可能同时在同一个单例上调用业务方法的任何其他客户端。

我建议使用这部分文档:

如果可以与许多客户端同时访问或共享该方法,则使用 @Lock(READ) 注释单例的业务或超时方法。如果在客户端调用该方法时单例会话 bean 应锁定到其他客户端,则使用 @Lock(WRITE) 注释业务或超时方法。通常,@Lock(WRITE) 注解在客户端修改单例状态时使用。

或者您可以使用bean-managed concurency 自行控制同步过程。然后你需要添加synchronized 锁或任何你用来控制对共享资源的访问的东西。在这种情况下,Container 不会参与其中。

【讨论】:

    【解决方案2】:

    不,它不会抛出任何异常,如果你使用容器,容器会让你的 99 个线程等待,而那个线程将访问方法

    @ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
    

    @Lock(WRITE)  
    

    几乎与使用同步块一样。

    但是,如果您假设在同步方法上可能会阻塞这么多线程,那么它看起来是一个糟糕的设计。

    为什么你需要你的 DAO 是一个单例?我会说这不是典型的。

    【讨论】:

    • 我不需要我的 DAO 是单例的。只是从来没想过。感谢您的澄清!
    猜你喜欢
    • 1970-01-01
    • 2011-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多