All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hibernate.engine.transaction.internal.TransactionImpl Maven / Gradle / Ivy

There is a newer version: 7.0.0.Beta1
Show newest version
/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
 * See the lgpl.txt file in the root directory or .
 */
package org.hibernate.engine.transaction.internal;

import javax.transaction.Synchronization;

import org.hibernate.HibernateException;
import org.hibernate.TransactionException;
import org.hibernate.engine.spi.ExceptionConverter;
import org.hibernate.engine.transaction.spi.TransactionImplementor;
import org.hibernate.internal.CoreLogging;
import org.hibernate.resource.transaction.spi.TransactionCoordinator;
import org.hibernate.resource.transaction.spi.TransactionStatus;

import org.jboss.logging.Logger;

import static org.hibernate.resource.transaction.spi.TransactionCoordinator.TransactionDriver;

/**
 * @author Andrea Boriero
 * @author Steve Ebersole
 */
public class TransactionImpl implements TransactionImplementor {
	private static final Logger LOG = CoreLogging.logger( TransactionImpl.class );

	private final TransactionCoordinator transactionCoordinator;
	private final ExceptionConverter exceptionConverter;
	private TransactionDriver transactionDriverControl;

	public TransactionImpl(TransactionCoordinator transactionCoordinator, ExceptionConverter exceptionConverter) {
		this.transactionCoordinator = transactionCoordinator;
		this.exceptionConverter = exceptionConverter;
		transactionDriverControl = transactionCoordinator.getTransactionDriverControl();
	}

	@Override
	public void begin() {
		if ( !transactionCoordinator.isActive() ) {
			throw new TransactionException( "Cannot begin Transaction on closed Session/EntityManager" );
		}

		if ( transactionDriverControl == null ) {
			transactionDriverControl = transactionCoordinator.getTransactionDriverControl();
		}

		// per-JPA
		if ( isActive() ) {
			throw new IllegalStateException( "Transaction already active" );
		}

		LOG.debug( "begin" );
		this.transactionDriverControl.begin();
	}

	@Override
	public void commit() {
		if ( !isActive() ) {
			// allow MARKED_ROLLBACK to propagate through to transactionDriverControl
			throw new IllegalStateException( "Transaction not successfully started" );
		}

		LOG.debug( "committing" );
		try {
			internalGetTransactionDriverControl().commit();
		}
		catch (RuntimeException e) {
			throw exceptionConverter.convertCommitException( e );
		}
	}

	public TransactionDriver internalGetTransactionDriverControl() {
		// NOTE here to help be a more descriptive NullPointerException
		if ( this.transactionDriverControl == null ) {
			throw new IllegalStateException( "Transaction was not properly begun/started" );
		}
		return this.transactionDriverControl;
	}

	@Override
	public void rollback() {
		// todo : may need a "JPA compliant" flag here

		TransactionStatus status = getStatus();
		if ( status == TransactionStatus.ROLLED_BACK || status == TransactionStatus.NOT_ACTIVE ) {
			// Allow rollback() calls on completed transactions, just no-op.
			LOG.debug( "rollback() called on an inactive transaction" );
			return;
		}

		if ( !status.canRollback() ) {
			throw new TransactionException( "Cannot rollback transaction in current status [" + status.name() + "]" );
		}

		LOG.debug( "rolling back" );
		if ( status != TransactionStatus.FAILED_COMMIT || allowFailedCommitToPhysicallyRollback() ) {
			internalGetTransactionDriverControl().rollback();
		}
	}

	@Override
	public boolean isActive() {
		// old behavior considered TransactionStatus#MARKED_ROLLBACK as active
		return isActive( true );
	}

	@Override
	public boolean isActive(boolean isMarkedForRollbackConsideredActive) {
		if ( transactionDriverControl == null ) {
			transactionDriverControl = transactionCoordinator.getTransactionDriverControl();
		}
		return transactionDriverControl.isActive( isMarkedForRollbackConsideredActive );
	}

	@Override
	public TransactionStatus getStatus() {
		if ( transactionDriverControl == null ) {
			transactionDriverControl = transactionCoordinator.getTransactionDriverControl();
		}
		return transactionDriverControl.getStatus();
	}

	@Override
	public void registerSynchronization(Synchronization synchronization) throws HibernateException {
		this.transactionCoordinator.getLocalSynchronizations().registerSynchronization( synchronization );
	}

	@Override
	public void setTimeout(int seconds) {
		this.transactionCoordinator.setTimeOut( seconds );
	}

	@Override
	public int getTimeout() {
		return this.transactionCoordinator.getTimeOut();
	}

	@Override
	public void setRollbackOnly() {
		internalGetTransactionDriverControl().markRollbackOnly();
	}

	@Override
	public boolean getRollbackOnly() {
		return getStatus() == TransactionStatus.MARKED_ROLLBACK;
	}

	protected boolean allowFailedCommitToPhysicallyRollback() {
		return false;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy