سؤال

I have a SLSB which increments a number in an entity. If two threads reach the SLSB at the same time, I'm getting the same number in both requests.

SLSB extract

@Stateless(mappedName = "ejb/CustomerManager")
public class CustomerManagerBean implements CustomerManager {
...
    public String recoverName(int id) {
        Customer customer = (Customer) em.createQuery("from Customer where id = :id").setParameter("id", id).getSingleResult();     
        int oldValue = customer.getValue();
        int newValue = oldValue + 1;
        customer.setValue(newValue);        
     [BP]   return customer.getName() + " value=" + customer.getValue();
    }
...
}

Entity extract

@Entity
public class Customer implements Serializable {
    @Id
    private int id;
    private int value;
}

To test the problem, I have a breakpoint at the line marked with [BP] in the SLSB recoverName method. Then a make two calls from two separated browser pages. At the breakpoint the value is the same for the two calls.

Shouldn't the second call throw some kind of exception when it tried to modify the value with the setter ?

I'm using JBoss 5 as the AS and MySql or Oracle as the DB (tried with both)

Thanks for the help

هل كانت مفيدة؟

المحلول

You would get an exception at flush time if you added a @Version annotated field to your entity, which would be used by JPA for optimistic locking.

Each time JPA updates an entity, it would compare the version in memory with the version in database, and would throw an exception if they don't match. If they match, the version would be incremented.

Just add the following to your entity:

@Column(name = "version")
@Version
private long version;

(and add the corresponding column to the database, of course)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top