容器管理事务无法回滚

我正在玩交易。

我配置JPA来处理我的实体,并希望将它们保存在数据库中。 问题是,当我的程序抛出runtimeException时,CMT不会回滚。

这个“容器事物”背后的想法很难理解,而且记录很少。

@transactional托管事务,纯CDI Interceptor托管事务和Bean管理事务就像一个魅力。

这是我编码的内容:这是一个简单的“电影演示”。 你想看两部带X座位的电影。 座位有限。 如果电影中的座位不足,则不应该有交易(ACID和东西)


在我的buyTicketsBoundary类:

起初我告诉我的class级我们正在使用CMT:

@Named("buchungBoundry") @RequestScoped @TransactionManagement(TransactionManagementType.CONTAINER) public class BuchungBoundry { @EJB private BuchungVerwaltung buyTicketsController; @EJB private KundenVerwaltung customerController; @EJB private SaalVerwaltung roomController; @EJB private MovieVerwaltung movieController; private int ticketsForMovie1; //this is how many tickets we want to buy private int ticketsForMovie2; public BuchungBoundry() { } @TransactionAttribute(TransactionAttributeType.REQUIRED) public void buyTickets() throws MyException { int numberOfSeantsInRoom1=roomController.getSaal(4).getAnzahlPlaetze(); int numberOfSeantsInRoom2=roomController.getSaal(5).getAnzahlPlaetze(); int alreadyBoughtSeatsIn1=buyTicketsController.getBelegtePlatzeNachSaal(4); int alreadyBoughtSeatsIn2=buyTicketsController.getBelegtePlatzeNachSaal(5); int availableSeats1 = numberOfSeantsInRoom1 - alreadyBoughtSeatsIn1; int availableSeats2 = numberOfSeantsInRoom2 - alreadyBoughtSeatsIn2; System.out.println("Saal A: ("+alreadyBoughtSeatsIn1+"/"+numberOfSeantsInRoom1+") want to buy :" + ticketsForMovie1); System.out.println("Saal B: ("+alreadyBoughtSeatsIn2+"/"+numberOfSeantsInRoom2+") want to buy :" + ticketsForMovie2); try { if (ticketsForMovie1 <= availableSeats1) { buyTicketsController.erstelleBuchung(customerController.getKunde(1), movieController.getMovie(7), roomController.getSaal(4), ticketsForMovie1); } else { throw new MyException("ERROR: no room for " + ticketsForMovie1 + " person! " +alreadyBoughtSeatsIn1); } if (ticketsForMovie2 <= availableSeats2) { buyTicketsController.erstelleBuchung(customerController.getKunde(1), movieController.getMovie(8), roomController.getSaal(5), ticketsForMovie2); } else { throw new MyException("ERROR: no room for " + ticketsForMovie2 + " person! " +alreadyBoughtSeatsIn2); } } catch (MyException | IllegalStateException | SecurityException ex) { Logger.getLogger(BuchungBoundry.class.getName()).log(Level.SEVERE, null, ex); } } 

我的例外:

 @ApplicationException(rollback=true) public class MyException extends RuntimeException{ public MyException() { } public MyException(String s) { System.out.println(""+s); } } 

Controller类通过JPA在数据库中写入Bought票证:

 @Stateless public class BuchungVerwaltung implements Serializable { @PersistenceContext(unitName = "kbse-JTA") private EntityManager em; public BuchungVerwaltung() { } public void erstelleBuchung(Kunde k, Movie movie, Saal saal, int anzahlPlaetze) { Buchung b = new Buchung(k, movie, saal, anzahlPlaetze); em.persist(b); } public int getBelegtePlatzeNachSaal(int id) { try { Query query = em.createNativeQuery("select sum(b.ANZAHL) from SAAL s,BUCHUNG b where s.SAAL_ID = b.SAAL_SAAL_ID and s.SAAL_ID=?"); query.setParameter(1, id); return (int) query.getSingleResult(); } catch (Exception e) { return 0; } } public List getAlleBuchungen() { TypedQuery query = em.createQuery("select s from Buchung s", Buchung.class); return query.getResultList(); } } 

问题是,当此类到达第一部电影的em.persist状态,而第二部电影抛出exception时,数据库无法回滚。

我想如果抛出RuntimeException,Container就会回滚

我能做些什么才能让它发挥作用?

如果有些事情不清楚,请告诉我

我做了一切corectly,唯一的错误是捕获“myException”

 } catch (MyException | IllegalStateException | SecurityException ex) { 

 } catch ( IllegalStateException | SecurityException ex) { 

现在好了,容器可以像它应该的那样回滚