JPA和EJB - 我什么时候需要使用事务?

Mar*_*rco 2 ejb jpa transactions jta java-ee

我正在学习一些教程后的Java持久性.

我正在使用Java EE 7和Payara服务器.

我注意到每个使用不同的持久性方法.

例子:

  • 简单

    @Stateless
    public class BookServiceBean implements BookService {
        @PersistenceContext
        private EntityManager em;
    
        public void createOrUpdate(Book book) {
            em.persist(book);
        }
        public void remove(Book book) {
            em.remove(book);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • with flush(),这是在persistene.xml中的 "AUTO"上没有设置验证策略时使用的,对吧?

    @Stateless
    public class BookServiceBean implements BookService {
        @PersistenceContext
        private EntityManager em;
    
        public void createOrUpdate(Book book) {
            em.persist(book);
            em.flush();
        }
        public void remove(Book book) {
            em.remove(book);
            em.flush();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 与交易

    @Stateless
    public class BookServiceBean implements BookService {
        @PersistenceContext
        private EntityManager em;
    
        public void createOrUpdate(Book book) {
            utx.begin();
            em.persist(book);
            utx.commit();
        }
        public void remove(Book book) {
            utx.begin();
            em.remove(book);
            utx.commit();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

何时以及为什么我必须使用最后一个?

是否有必要em.close()在每种方法的最后使用?

有什么好的做法?

Bal*_*usC 5

第一个是没有所有手动刷新和事务模糊的EJB方法,是规范的方法.默认情况下,单个EJB方法调用已计为单个完整事务.EJB容器将在调用方法之前透明地开始事务,并在方法返回时提交事务(或者在从方法抛出应用程序异常时回滚).

第二个例子中的手动冲洗是不必要的.通常,您只想em.flush()在修改实体时使用(即使其变为"脏")并且希望事后(间接)SELECT在同一事务中执行它.它很少见,但它有真实世界的用例,通常当你想要SELECT一个脏实体是其子代的父类时.

第三个例子中的手动事务管理是完全没有必要的.读完第一段后你应该已经意识到了.只有在不使用时才需要手动事务管理JTA,但RESOURCE_LOCAL(通常在Java SE中不是Java EE).

也可以看看: