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);
}
}
}
}
}