I'm implementing Non-repeatable read isolation level on WildFly 9.0.2 in a @Stateless
rest resource
- Thread A is reading a
Account
entity, prints the balance and then do some other work (sleep). - Thread B comes in and read the same
Account
entity, prints the balance and calculates the balance viacalculateBalance()
method and then update the entity. It reads the entity again and prints out the balance. - Thread A then reads the entity and prints out the balance.
According to my understanding of the Non-Repeatable read level Thread B should block until Thread A completely finish (Exit the transaction/Stateless rest resource).
Here is the printout:
- Thread A: printBalance=500
- Thread B: printBalance=500
- Thread B: printBalance=600
- Thread A: printBalance=500
From that I can see Thread B is not blocking and is allowed to run even though Thread A is still busy.
Below is the code:
@GET
@Path("/{accountId}/{threadName}")
public Response calculcateBalance(@PathParam("accountId") Long accountId, @PathParam("threadName") String threadName) {
Account account = em.find(Account.class, accountId);
printBalance(account,threadName);
if ("ThreadA".equals(threadName)) {
sleepSeconds(10);
} else if ("ThreadB".equals(threadName)) {
account.calculateBalance();
em.merge(account);
}
account = em.find(Account.class, accountId);
printBalance(account,threadName);
return Response.ok().build();
}
If I change the isolation level to Serializable everything blocks.
Is my understanding of Non-repeatable read wrong? Should Thread B not be blocked until Thread A is finished?