2

現在、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 番目のトランザクションはロールバックされているはずです。

ここで何かが恋しいですか?どうすればこの問題を解決できますか?

4

0 に答える 0