package org.javaee7.jpa.locking.optimistic;
import static java.util.concurrent.TimeUnit.SECONDS;
import static javax.ejb.TransactionAttributeType.REQUIRED;
import java.util.concurrent.CountDownLatch;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.enterprise.inject.Alternative;
/**
* @author Roberto Cortez
*/
@Alternative
@Stateless
public class MovieBeanAlternative extends MovieBean {
public static CountDownLatch lockCountDownLatch = new CountDownLatch(1);
public static CountDownLatch readCountDownLatch = new CountDownLatch(1);
@Override
@TransactionAttribute(REQUIRED)
public Movie readMovie(Integer id) {
System.out.println("MovieBeanAlternative.readMovie");
Movie movie = super.readMovie(id);
try {
readCountDownLatch.await(10, SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
return movie;
}
@Override
@TransactionAttribute(REQUIRED)
public void updateMovie(Integer id, String name) {
System.out.println("MovieBeanAlternative.updateMovie");
super.updateMovie(id, name);
try {
System.out.println("MovieBeanAlternative.updateMovie waiting for lockCountDownLatch");
lockCountDownLatch.await(10, SECONDS);
System.out.println("MovieBeanAlternative.updateMovie done waiting for lockCountDownLatch");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
@TransactionAttribute(REQUIRED)
public void updateMovie2(Integer id, String name) {
System.out.println("MovieBeanAlternative.updateMovie2");
System.out.println("MovieBeanAlternative.updateMovie2 Reading entity");
// We're reading the movie first, with the attention for this movie to become "stale"
Movie movie = super.readMovie(id);
try {
// Now wait for the movie to be deleted by the other thread
System.out.println("MovieBeanAlternative.updateMovie2 waiting for lockCountDownLatch");
boolean gotLock = lockCountDownLatch.await(10, SECONDS);
System.out.println("MovieBeanAlternative.updateMovie2 done waiting for lockCountDownLatch. Got lock:" + gotLock);
} catch (InterruptedException e) {
e.printStackTrace();
}
// If we got the lock from the lockCountDownLatch, then it means the movie has been deleted.
// If we try to update the movie now it has to throw an OptimisticLockException
// (if we didn't got the lock the test will just fail)
super.updateMovie(movie, name);
}
@Override
@TransactionAttribute(REQUIRED)
public void deleteMovie(Integer id) {
System.out.println("MovieBeanAlternative.deleteMovie");
super.deleteMovie(id);
}
}