3

Using Java 7 with Jboss7 the following code used to work.

@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();

    }
}

Now I've migrated to Java 8 with Wildfly it stopped working. If geraEIniciaOperacao is still running, I can't access getOperacaoEmAndamento.

" javax.ejb.ConcurrentAccessTimeoutException: WFLYEJB0241: EJB 3.1 PFD2 4.8.5.5.1 concurrent access timeout on OperacaoServiceImpl - could not obtain lock within 5000MILLISECONDS at org.jboss.as.ejb3.concurrency.ContainerManagedConcurrencyInterceptor.processInvocation(ContainerManagedConcurrencyInterceptor.java:106) ..."

Camilla
  • 489
  • 5
  • 14

1 Answers1

1

I couldn't understand why something like this used to work. But what I've found is: with container managed concurrency the semantics is "concurrent reads are allowed as long as no writing is going on". What I need is "concurrent reads are allowed, also while writing goes on, but only one thread will be writing at a time". To achieve that I've changed the class to

@Lock(LockType.READ)

@Singleton

public class OperacaoServiceImpl implements OperacaoService {

and the method

public void geraEIniciaOperacao() throws CoreException {

to

syncronized public void geraEIniciaOperacao() throws CoreException {

Reference: EJB 3.1 container managed concurrency vs. synchronized

Community
  • 1
  • 1
Camilla
  • 489
  • 5
  • 14
  • What you just described is how you create a race condition. You cannot have reads and writes happening at the same time (non-atomically) and expect integrity of your results. You just can't. This isn't a JavaEE problem, or even just a JavaSE problem - this is how parallel computing works in general. – searchengine27 Feb 24 '20 at 21:42
  • 2
    Also, you're violating the EJB contract by putting the `synchronized` keyword on the method. 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`. Absolutely, **DO NOT** do this. I gave a -1 for suggesting doing reads and writes without guarding when I read that, but violating the EJB spec would earn another -1 if I could. The EJB spec exists for a reason: portability. Don't violate it. – searchengine27 Feb 24 '20 at 21:50