jtatransaction.java

来自「hibernate-distribution-3.3.1.GA-dist.zip」· Java 代码 · 共 360 行

JAVA
360
字号
/* * Hibernate, Relational Persistence for Idiomatic Java * * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors.  All third-party contributions are * distributed under license by Red Hat Middleware LLC. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA  02110-1301  USA * */package org.hibernate.transaction;import javax.transaction.Status;import javax.transaction.Synchronization;import javax.transaction.SystemException;import javax.transaction.TransactionManager;import javax.transaction.UserTransaction;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.hibernate.HibernateException;import org.hibernate.Transaction;import org.hibernate.TransactionException;import org.hibernate.jdbc.JDBCContext;import org.hibernate.util.JTAHelper;/** * {@link Transaction} implementation based on transaction management through * a JTA {@link UserTransaction}.  Similar to {@link CMTTransaction}, except * here we are actually managing the transactions through the Hibernate * transaction mechanism. * * @author Gavin King * @author Steve Ebersole * @author Les Hazlewood */public class JTATransaction implements Transaction {	private static final Logger log = LoggerFactory.getLogger( JTATransaction.class );	private final JDBCContext jdbcContext;	private final TransactionFactory.Context transactionContext;	private UserTransaction userTransaction;	private boolean newTransaction;	private boolean begun;	private boolean commitFailed;	private boolean commitSucceeded;	private boolean callback;	public JTATransaction(			UserTransaction userTransaction,			JDBCContext jdbcContext,			TransactionFactory.Context transactionContext) {		this.jdbcContext = jdbcContext;		this.transactionContext = transactionContext;		this.userTransaction = userTransaction;	}	/**	 * {@inheritDoc}	 */	public void begin() throws HibernateException {		if ( begun ) {			return;		}		if ( commitFailed ) {			throw new TransactionException( "cannot re-start transaction after failed commit" );		}		log.debug( "begin" );		try {			newTransaction = userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION;			if ( newTransaction ) {				userTransaction.begin();				log.debug( "Began a new JTA transaction" );			}		}		catch ( Exception e ) {			log.error( "JTA transaction begin failed", e );			throw new TransactionException( "JTA transaction begin failed", e );		}		/*if (newTransaction) {			// don't need a synchronization since we are committing			// or rolling back the transaction ourselves - assuming			// that we do no work in beforeTransactionCompletion()			synchronization = false;		}*/		boolean synchronization = jdbcContext.registerSynchronizationIfPossible();		if ( !newTransaction && !synchronization ) {			log.warn( "You should set hibernate.transaction.manager_lookup_class if cache is enabled" );		}		if ( !synchronization ) {			//if we could not register a synchronization,			//do the before/after completion callbacks			//ourself (but we need to let jdbcContext			//know that this is what we are going to			//do, so it doesn't keep trying to register			//synchronizations)			callback = jdbcContext.registerCallbackIfNecessary();		}		begun = true;		commitSucceeded = false;		jdbcContext.afterTransactionBegin( this );	}	/**	 * {@inheritDoc}	 */	public void commit() throws HibernateException {		if ( !begun ) {			throw new TransactionException( "Transaction not successfully started" );		}		log.debug( "commit" );		boolean flush = !transactionContext.isFlushModeNever()				&& ( callback || !transactionContext.isFlushBeforeCompletionEnabled() );		if ( flush ) {			transactionContext.managedFlush(); //if an exception occurs during flush, user must call rollback()		}		if ( callback && newTransaction ) {			jdbcContext.beforeTransactionCompletion( this );		}		closeIfRequired();		if ( newTransaction ) {			try {				userTransaction.commit();				commitSucceeded = true;				log.debug( "Committed JTA UserTransaction" );			}			catch ( Exception e ) {				commitFailed = true; // so the transaction is already rolled back, by JTA spec				log.error( "JTA commit failed", e );				throw new TransactionException( "JTA commit failed: ", e );			}			finally {				afterCommitRollback();			}		}		else {			// this one only really needed for badly-behaved applications!			// (if the TransactionManager has a Sychronization registered,			// its a noop)			// (actually we do need it for downgrading locks)			afterCommitRollback();		}	}	/**	 * {@inheritDoc}	 */	public void rollback() throws HibernateException {		if ( !begun && !commitFailed ) {			throw new TransactionException( "Transaction not successfully started" );		}		log.debug( "rollback" );		try {			closeIfRequired();		}		catch ( Exception e ) {			// swallow it, and continue to roll back JTA transaction			log.error( "could not close session during rollback", e );		}		try {			if ( newTransaction ) {				if ( !commitFailed ) {					userTransaction.rollback();					log.debug( "Rolled back JTA UserTransaction" );				}			}			else {				userTransaction.setRollbackOnly();				log.debug( "set JTA UserTransaction to rollback only" );			}		}		catch ( Exception e ) {			log.error( "JTA rollback failed", e );			throw new TransactionException( "JTA rollback failed", e );		}		finally {			afterCommitRollback();		}	}	private static final int NULL = Integer.MIN_VALUE;	private void afterCommitRollback() throws TransactionException {		begun = false;		// this method is a noop if there is a Synchronization!		if ( callback ) {			if ( !newTransaction ) {				log.warn( "You should set hibernate.transaction.manager_lookup_class if cache is enabled" );			}			int status = NULL;			try {				status = userTransaction.getStatus();			}			catch ( Exception e ) {				log.error( "Could not determine transaction status after commit", e );				throw new TransactionException( "Could not determine transaction status after commit", e );			}			finally {				jdbcContext.afterTransactionCompletion( status == Status.STATUS_COMMITTED, this );			}		}	}	/**	 * {@inheritDoc}	 */	public boolean wasRolledBack() throws TransactionException {		final int status;		try {			status = userTransaction.getStatus();		}		catch ( SystemException se ) {			log.error( "Could not determine transaction status", se );			throw new TransactionException( "Could not determine transaction status", se );		}		if ( status == Status.STATUS_UNKNOWN ) {			throw new TransactionException( "Could not determine transaction status" );		}		else {			return JTAHelper.isRollback( status );		}	}	/**	 * {@inheritDoc}	 */	public boolean wasCommitted() throws TransactionException {		final int status;		try {			status = userTransaction.getStatus();		}		catch ( SystemException se ) {			log.error( "Could not determine transaction status", se );			throw new TransactionException( "Could not determine transaction status: ", se );		}		if ( status == Status.STATUS_UNKNOWN ) {			throw new TransactionException( "Could not determine transaction status" );		}		else {			return status == Status.STATUS_COMMITTED;		}	}	/**	 * {@inheritDoc}	 */	public boolean isActive() throws TransactionException {		if ( !begun || commitFailed || commitSucceeded ) {			return false;		}		final int status;		try {			status = userTransaction.getStatus();		}		catch ( SystemException se ) {			log.error( "Could not determine transaction status", se );			throw new TransactionException( "Could not determine transaction status: ", se );		}		if ( status == Status.STATUS_UNKNOWN ) {			throw new TransactionException( "Could not determine transaction status" );		}		else {			return status == Status.STATUS_ACTIVE;		}	}	/**	 * {@inheritDoc}	 */	public void registerSynchronization(Synchronization sync) throws HibernateException {		if ( getTransactionManager() == null ) {			throw new IllegalStateException( "JTA TransactionManager not available" );		}		else {			try {				getTransactionManager().getTransaction().registerSynchronization( sync );			}			catch ( Exception e ) {				throw new TransactionException( "could not register synchronization", e );			}		}	}	/**	 * Getter for property 'transactionManager'.	 *	 * @return Value for property 'transactionManager'.	 */	private TransactionManager getTransactionManager() {		return transactionContext.getFactory().getTransactionManager();	}	private void closeIfRequired() throws HibernateException {		boolean close = callback &&				transactionContext.shouldAutoClose() &&				!transactionContext.isClosed();		if ( close ) {			transactionContext.managedClose();		}	}	/**	 * {@inheritDoc}	 */	public void setTimeout(int seconds) {		try {			userTransaction.setTransactionTimeout( seconds );		}		catch ( SystemException se ) {			throw new TransactionException( "could not set transaction timeout", se );		}	}	/**	 * Getter for property 'userTransaction'.	 *	 * @return Value for property 'userTransaction'.	 */	protected UserTransaction getUserTransaction() {		return userTransaction;	}}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?