質問

I have such code :

   public void createTerminal(TerminalDo terminalDo) {
        final EntityManagerFactory emf = JpaFactory.getEntityManagerFactory();
        final EntityManager em = emf.createEntityManager();
        EntityTransaction etx = null;
        try {
            etx = em.getTransaction();
            etx.begin();

            // persist method make the passed Object stored in the persistence
            // context
            em.persist(terminalDo);

            etx.commit();
        } catch (Exception e) {
            if (etx != null && etx.isActive())
                etx.rollback();
            e.printStackTrace();
        } finally {
            em.close();
        }
   }

This is a transactional method. I don't know if it's possible to create another transactional method calling this already transactional one, then nesting an entity-managed transaction into another one, and is it a good practice ?

       public void makeAllThat(TerminalDo terminalDo, ApplicationDo applicationDo) {
            final EntityManagerFactory emf = JpaFactory.getEntityManagerFactory();
            final EntityManager em = emf.createEntityManager();
            EntityTransaction etx = null;
            try {
                etx = em.getTransaction();
                etx.begin();

                createTerminal(terminalDo);
                createApplication(applicationDo);
                //do many other transactions...
                .....

                etx.commit();
            } catch (Exception e) {
                if (etx != null && etx.isActive())
                    etx.rollback();
                e.printStackTrace();
            } finally {
                em.close();
            }
       }
役に立ちましたか?

解決

What you ask is called Nested Transactions. JPA alone does not specify anything about that. A Persistence Unit can be of two types: RESOURCE_LOCAL (your case, as you work with EntityTransaction) and JTA. Also JTA is known as not requiring nested transactions. But your case is RESOURCE_LOCAL, which AFIK depends on your JDBC driver, database and database engine.

IMPORTANT NOTE: the example that you showed is an example of parallel transactions, as every EntityManager instance you create with EntityManagerFactory.createEntityManager()' is independent of each other. In your case, ifcreateApplication()fails,createTerminal()` will have its transaction commited (please do test it and comfirm that in a comment)!

Usually you come along without nested transaction and I would suggest using JTA transaction (with a framework that supports declarative transactions, like Spring or EJB), as it is really a standard nowadays.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top