現在、JavaEE 6 のトランザクション処理について勉強していますが、少し行き詰まっています。
誰かがセミナーで 1 人以上の人を予約できるセミナー予約エンジンをシミュレートします。私のエンティティは次のようになります。
@Entity
@XmlRootElement
public class Seminar {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@Version
private Long version;
private Integer freeCapacity;
... //getters & setters
}
これは EJB です。
@Stateless
public class SeminarBooking {
@PersistenceContext
EntityManager em;
@Inject
Event<Seminar> txListeners;
public boolean bookSeminar(Long seminarId, int numberOfPersons) {
Seminar seminar = em.find(Seminar.class, seminarId);
Integer freeCapacity = seminar.getFreeCapacity();
if((freeCapacity - numberOfPersons) >= 0) {
//setting free capacity after booking
seminar.setFreeCapacity(freeCapacity - numberOfPersons);
txListeners.fire(seminar);
return true;
}
return false;
}
}
私のトランザクション リスナーは次のようになります。
public class TxListener {
public void onSuccess(@Observes(during=TransactionPhase.AFTER_SUCCESS) Seminar seminar) {
//omitted retrieving of minute,second,milli
logger.fine("Successful booking -- " + minute + ":" + second + ":" + milli + " FreeCapacity: "+seminar.getFreeCapacity());
}
}
問題は、バックエンドで 100 個のスレッドを並行して実行し、次のようなログ エントリを取得していることです。
Successful booking -- 24:50:51 FreeCapacity: 9641
Successful booking -- 24:50:61 FreeCapacity: 9641
Successful booking -- 24:50:54 FreeCapacity: 9641
Successful booking -- 24:50:637 FreeCapacity: 9639
同じ値の freeCapacity を持つ成功した (コミットされた) トランザクションが存在するのはどうしてでしょうか?
私の意見ではOptimisticLockException
、1 番目のトランザクションがエンティティのバージョン フィールドを更新したため、2 番目と 3 番目のトランザクションは をスローする必要があります。したがって、2 番目と 3 番目のトランザクションはロールバックされているはずです。
ここで何かが恋しいですか?どうすればこの問題を解決できますか?