/* * Hibernate OGM, Domain model persistence for NoSQL datastores * * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.ogm.compensation.impl; import org.hibernate.engine.transaction.spi.TransactionObserver; import org.hibernate.ogm.compensation.ErrorHandler; import org.hibernate.ogm.transaction.impl.ForwardingTransactionCoordinator; import org.hibernate.resource.transaction.TransactionCoordinator; /** * A {@link TransactionCoordinator} invoking the registered {@link ErrorHandler} upon rollbacks. * * @author Gunnar Morling */ public class ErrorHandlerEnabledTransactionCoordinatorDecorator extends ForwardingTransactionCoordinator { private final ErrorHandler errorHandler; private OperationCollector operationCollector; public ErrorHandlerEnabledTransactionCoordinatorDecorator(TransactionCoordinator delegate, ErrorHandler errorHandler) { super( delegate ); this.errorHandler = errorHandler; delegate.addObserver( new OperationCollectorObserver() ); } public OperationCollector getOperationCollector() { return operationCollector; } @Override public TransactionDriver getTransactionDriverControl() { // Create the collector upon first usage in a given TX (not done via TransactionObserver#afterBegin() as it is // not invoked in the case of JTA if ( operationCollector == null ) { operationCollector = new OperationCollector( errorHandler ); } return super.getTransactionDriverControl(); } /** * Invokes the error handler upon TX rollback. Implemented via a observer as this nicely works for local and JTA * transactions. */ private class OperationCollectorObserver implements TransactionObserver { @Override public void afterBegin() { // Nothing to do } @Override public void beforeCompletion() { // Nothing to do } @Override public void afterCompletion(boolean successful, boolean delayed) { if ( !successful ) { errorHandler.onRollback( operationCollector ); } operationCollector = null; } } }