protected Object proceedMethodInTransaction()

in jee-modules/jpa-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jpa/impl/LegacyTransactionalInterceptorStrategy.java [209:332]


    protected Object proceedMethodInTransaction(InvocationContext context,
                                                EntityManagerEntry entityManagerEntry,
                                                EntityManager entityManager) throws Exception
    {
        // used to store any exception we get from the services
        Exception firstException = null;

        try
        {
            beginTransaction(entityManager);
            refCount.get().incrementAndGet();

            return context.proceed();

        }
        catch(Exception e)
        {
            firstException = e;

            // we only cleanup and rollback all open transactions in the outermost interceptor!
            // this way, we allow inner functions to catch and handle exceptions properly.
            if (refCount.get().intValue() == 1)
            {
                for (EntityManager currentEntityManager : entityManagerMap.get().values())
                {
                    try
                    {
                        rollbackTransaction(currentEntityManager);
                    }
                    catch (Exception eRollback)
                    {
                        LOGGER.log(Level.SEVERE, "Got additional Exception while subsequently " +
                                "rolling back other SQL transactions", eRollback);
                    }
                }

                refCount.remove();

                // drop all EntityManagers from the ThreadLocal
                entityManagerMap.remove();
            }

            // rethrow the exception
            throw e;

        }
        finally
        {
            if (refCount.get() != null)
            {
                refCount.get().decrementAndGet();


                // will get set if we got an Exception while committing
                // in this case, we rollback all later transactions too.
                boolean commitFailed = false;

                // commit all open transactions in the outermost interceptor!
                // this is a 'JTA for poor men' only, and will not guaranty
                // commit stability over various databases!
                if (refCount.get().intValue() == 0)
                {
                    // only commit all transactions if we didn't rollback
                    // them already
                    if (firstException == null)
                    {
                        // first flush all EntityManagers
                        for (EntityManager currentEntityManager : entityManagerMap.get().values())
                        {
                            try
                            {
                                currentEntityManager.flush();
                            }
                            catch (Exception e)
                            {
                                firstException = e;
                                commitFailed = true;
                                break;
                            }
                        }

                        EntityTransaction transaction;
                        // and finally do all the commits
                        for (EntityManager currentEntityManager : entityManagerMap.get().values())
                        {
                            transaction = currentEntityManager.getTransaction();
                            if(transaction != null && transaction.isActive())
                            {
                                try
                                {
                                    if (!commitFailed)
                                    {
                                        commitTransaction(currentEntityManager);
                                    }
                                    else
                                    {
                                        rollbackTransaction(currentEntityManager);
                                    }
                                }
                                catch (Exception e)
                                {
                                    firstException = e;
                                    commitFailed = true;
                                }
                            }
                        }
                    }

                    // finally remove all ThreadLocals
                    refCount.remove();
                    entityManagerMap.remove();

                    if(!commitFailed)
                    {
                        endProcess(entityManagerEntry, entityManager, null);
                    }
                    else
                    {
                        endProcess(entityManagerEntry, entityManager, firstException);
                    }
                }
            }
        }
    }