0

エンティティ内の数値をインクリメントするSLSBがあります。2つのスレッドが同時に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;
}

問題をテストするために、[BP]SLSBrecoverNameメソッドでマークされた行にブレークポイントがあります。次に、2つの別々のブラウザページから2つの呼び出しを行います。ブレークポイントでは、値は2つの呼び出しで同じです。

セッターで値を変更しようとしたときに、2番目の呼び出しが何らかの例外をスローするべきではありませんか?

ASとしてJBoss5を使用し、DBとしてMySqlまたはOracleを使用しています(両方で試してみました)

助けてくれてありがとう

4

1 に答える 1

4

エンティティに@Version注釈付きフィールドを追加した場合、フラッシュ時に例外が発生します。これは、JPAが楽観的ロックのために使用します。

JPAはエンティティを更新するたびに、メモリ内のバージョンとデータベース内のバージョンを比較し、それらが一致しない場合は例外をスローします。それらが一致する場合、バージョンがインクリメントされます。

エンティティに以下を追加するだけです。

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

(もちろん、対応する列をデータベースに追加します)

于 2012-07-03T12:57:24.727 に答える