【问题标题】:@Lock(LockType.READ) Singleton Ejb in java 8@Lock(LockType.READ) Java 8 中的单例 Ejb
【发布时间】:2016-07-21 14:38:13
【问题描述】:

将 Java 7 与 Jboss7 一起使用,以下代码可以正常工作。

@Singleton
public class OperacaoServiceImpl implements OperacaoService {

    private Operacao operacaoEmAndamento;

    @Override
    @Lock(LockType.READ)
    public Operacao getOperacaoEmAndamento() {
        return operacaoEmAndamento;
    }

    @Override
    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public void geraEIniciaOperacao() throws CoreException {
        geraOperacao();
        iniciaOperacao();

    }
}

现在我已经使用 Wildfly 迁移到 Java 8,但它停止了工作。如果 geraEIniciaOperacao 仍在运行,我无法访问 getOperacaoEmAndamento。

" javax.ejb.ConcurrentAccessTimeoutException: WFLYEJB0241: EJB 3.1 OperacaoServiceImpl 上的 PFD2 4.8.5.5.1 并发访问超时 - 无法在 5000 毫秒内获得锁定 org.jboss.as.ejb3.concurrency.ContainerManagedConcurrencyInterceptor.processInvocation(ContainerManagedConcurrencyInterceptor.java:106) ……”

【问题讨论】:

    标签: java-8 locking singleton


    【解决方案1】:

    我不明白为什么这样的事情曾经奏效。但我发现:使用容器管理的并发,语义是“只要不进行写入,就允许并发读取”。我需要的是“允许并发读取,在写入过程中也是如此,但一次只能写入一个线程”。为了实现这一点,我将课程更改为

    @Lock(LockType.READ)

    @Singleton

    公共类 OperacaoServiceImpl 实现 OperacaoService {

    方法

    public void geraEIniciaOperacao() 抛出 CoreException {

    同步的公共 void geraEIniciaOperacao() 抛出 CoreException {

    参考:EJB 3.1 container managed concurrency vs. synchronized

    【讨论】:

    • 您刚才描述的是如何创建竞态条件。您不能同时(非原子地)读取和写入并期望结果的完整性。你就是不能。这不是 JavaEE 问题,甚至不是 JavaSE 问题——这就是并行计算的一般工作原理。
    • 另外,您在方法上加上synchronized 关键字违反了EJB 合同。 JSR-345 16.2.2:An enterprise bean must not use thread synchronization primitives to synchronize execution of multiple instances, unless it is a singleton session bean with bean-managed concurrency。绝对,不要这样做。我给了一个-1,因为我建议在阅读时不加保护地进行读取和写入,但是如果可以的话,违反 EJB 规范将获得另一个-1。 EJB 规范的存在是有原因的:可移植性。不要违反它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-13
    • 1970-01-01
    • 1970-01-01
    • 2016-06-26
    • 1970-01-01
    • 2012-02-04
    • 2018-01-11
    相关资源
    最近更新 更多