【问题标题】:How to avoid concurrency in Stateless Session Bean?如何避免无状态会话 Bean 中的并发?
【发布时间】:2012-07-03 12:51:49
【问题描述】:

我有一个 SLSB,它增加实体中的数字。如果两个线程同时到达 SLSB,我会在两个请求中得到相同的数字。

SLSB 提取

@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
public class Customer implements Serializable {
    @Id
    private int id;
    private int value;
}

为了测试问题,我在 SLSB recoverName 方法中用[BP] 标记的行设置了一个断点。然后从两个分开的浏览器页面进行两次调用。在断点处,两个调用的值相同

第二个调用在尝试使用 setter 修改值时不应该抛出某种异常吗?

我使用 JBoss 5 作为 AS,使用 MySql 或 Oracle 作为 DB(两者都试过)

感谢您的帮助

【问题讨论】:

    标签: java ejb ejb-3.0 stateless-session-bean


    【解决方案1】:

    如果您向实体添加 @Version 注释字段,您将在刷新时收到异常,JPA 将使用该字段进行乐观锁定。

    JPA 每次更新实体时,都会将内存中的版本与数据库中的版本进行比较,如果不匹配则会抛出异常。如果它们匹配,则版本将递增。

    只需将以下内容添加到您的实体中:

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

    (当然是把对应的列添加到数据库中)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-31
      • 1970-01-01
      • 2013-08-02
      • 2011-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多