/* * Copyright open knowledge GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.openknowledge.cdi.transaction.jta; import javax.ejb.ApplicationException; import javax.enterprise.inject.Any; import javax.enterprise.inject.Instance; import javax.inject.Inject; import javax.persistence.EntityManager; import javax.transaction.HeuristicMixedException; import javax.transaction.HeuristicRollbackException; import javax.transaction.NotSupportedException; import javax.transaction.RollbackException; import javax.transaction.Status; import javax.transaction.SystemException; import javax.transaction.TransactionManager; import javax.transaction.UserTransaction; import java.io.Serializable; /** * Handles JTA transactions * * @author Arne Limburg - open knowledge GmbH */ public abstract class AbstractTransactionAttributeInterceptor implements Serializable { @Inject private UserTransactionHolder utHolder; @Inject @Any private Instance<EntityManager> entityManagers; public TransactionManager getTransactionManager() throws NotSupportedException { if (!(utHolder.getUserTransaction() instanceof TransactionManager)) { throw new NotSupportedException("Cannot receive TransactionManager"); } return (TransactionManager) utHolder.getUserTransaction(); } public boolean isTransactionActive() throws SystemException { return utHolder.getUserTransaction().getStatus() == Status.STATUS_ACTIVE; } public boolean isTransactionMarkedRollback() throws SystemException { return utHolder.getUserTransaction().getStatus() == Status.STATUS_MARKED_ROLLBACK; } public void markTransactionRollbackOnly() throws SystemException { utHolder.getUserTransaction().setRollbackOnly(); } public void beginTransaction() throws NotSupportedException, SystemException { utHolder.getUserTransaction().begin(); // this should not be necessary if (entityManagers != null) { for (EntityManager manager : entityManagers) { manager.joinTransaction(); } } } public void commitTransaction() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SystemException { utHolder.getUserTransaction().commit(); } public void rollbackTransaction() throws SystemException { utHolder.getUserTransaction().rollback(); } protected void rollbackTransactionIfNeeded(boolean responsible, Exception exception) throws SystemException { if (isTransactionActive()) { ApplicationException applicationException = exception.getClass().getAnnotation(ApplicationException.class); if (applicationException == null || applicationException.rollback()) { utHolder.getUserTransaction().setRollbackOnly(); } } } protected void handleTransactionEnd(boolean responsible) throws SystemException, RollbackException, HeuristicMixedException, HeuristicRollbackException { if (responsible) { if (isTransactionMarkedRollback()) { rollbackTransaction(); } else { commitTransaction(); } } } public void setUserTransaction(UserTransaction userTransaction) { this.utHolder = new DefaultUserTransactionHolder(userTransaction); } }