FileDocCategorySizeDatePackage
JDBCTransaction.javaAPI DocHibernate 3.2.56627Fri Mar 10 11:14:22 GMT 2006org.hibernate.transaction

JDBCTransaction

public class JDBCTransaction extends Object implements org.hibernate.Transaction
Implements a basic transaction strategy for JDBC connections.This is the default Transaction implementation used if none is explicitly specified.
author
Anton van Straaten, Gavin King

Fields Summary
private static final Log
log
private final org.hibernate.jdbc.JDBCContext
jdbcContext
private final TransactionFactory.Context
transactionContext
private boolean
toggleAutoCommit
private boolean
begun
private boolean
rolledBack
private boolean
committed
private boolean
commitFailed
private List
synchronizations
private boolean
callback
private int
timeout
Constructors Summary
public JDBCTransaction(org.hibernate.jdbc.JDBCContext jdbcContext, TransactionFactory.Context transactionContext)


	     
		this.jdbcContext = jdbcContext;
		this.transactionContext = transactionContext;
	
Methods Summary
public voidbegin()

		if (begun) {
			return;
		}
		if (commitFailed) {
			throw new TransactionException("cannot re-start transaction after failed commit");
		}

		log.debug("begin");

		try {
			toggleAutoCommit = jdbcContext.connection().getAutoCommit();
			if ( log.isDebugEnabled() ) {
				log.debug("current autocommit status: " + toggleAutoCommit);
			}
			if (toggleAutoCommit) {
				log.debug("disabling autocommit");
				jdbcContext.connection().setAutoCommit(false);
			}
		}
		catch (SQLException e) {
			log.error("JDBC begin failed", e);
			throw new TransactionException("JDBC begin failed: ", e);
		}

		callback = jdbcContext.registerCallbackIfNecessary();

		begun = true;
		committed = false;
		rolledBack = false;

		if ( timeout>0 ) {
			jdbcContext.getConnectionManager()
					.getBatcher()
					.setTransactionTimeout(timeout);
		}

		jdbcContext.afterTransactionBegin(this);
	
private voidcloseIfRequired()

		if ( callback && transactionContext.shouldAutoClose() && !transactionContext.isClosed() ) {
			try {
				transactionContext.managedClose();
			}
			catch (HibernateException he) {
				log.error("Could not close session", he);
				//swallow, the transaction was finished
			}
		}
	
public voidcommit()

		if (!begun) {
			throw new TransactionException("Transaction not successfully started");
		}

		log.debug("commit");

		if ( !transactionContext.isFlushModeNever() && callback ) {
			transactionContext.managedFlush(); //if an exception occurs during flush, user must call rollback()
		}

		notifyLocalSynchsBeforeTransactionCompletion();
		if ( callback ) {
			jdbcContext.beforeTransactionCompletion( this );
		}

		try {
			commitAndResetAutoCommit();
			log.debug("committed JDBC Connection");
			committed = true;
			if ( callback ) {
				jdbcContext.afterTransactionCompletion( true, this );
			}
			notifyLocalSynchsAfterTransactionCompletion( Status.STATUS_COMMITTED );
		}
		catch (SQLException e) {
			log.error("JDBC commit failed", e);
			commitFailed = true;
			if ( callback ) {
				jdbcContext.afterTransactionCompletion( false, this );
			}
			notifyLocalSynchsAfterTransactionCompletion( Status.STATUS_UNKNOWN );
			throw new TransactionException("JDBC commit failed", e);
		}
		finally {
			closeIfRequired();
		}
	
private voidcommitAndResetAutoCommit()

		try {
			jdbcContext.connection().commit();
		}
		finally {
			toggleAutoCommit();
		}
	
public booleanisActive()

		return begun && ! ( rolledBack || committed | commitFailed );
	
private voidnotifyLocalSynchsAfterTransactionCompletion(int status)

		begun = false;
		if (synchronizations!=null) {
			for ( int i=0; i<synchronizations.size(); i++ ) {
				Synchronization sync = (Synchronization) synchronizations.get(i);
				try {
					sync.afterCompletion(status);
				}
				catch (Throwable t) {
					log.error("exception calling user Synchronization", t);
				}
			}
		}
	
private voidnotifyLocalSynchsBeforeTransactionCompletion()

		if (synchronizations!=null) {
			for ( int i=0; i<synchronizations.size(); i++ ) {
				Synchronization sync = (Synchronization) synchronizations.get(i);
				try {
					sync.beforeCompletion();
				}
				catch (Throwable t) {
					log.error("exception calling user Synchronization", t);
				}
			}
		}
	
public voidregisterSynchronization(javax.transaction.Synchronization sync)

		if (sync==null) throw new NullPointerException("null Synchronization");
		if (synchronizations==null) {
			synchronizations = new ArrayList();
		}
		synchronizations.add(sync);
	
public voidrollback()


		if (!begun && !commitFailed) {
			throw new TransactionException("Transaction not successfully started");
		}

		log.debug("rollback");

		if (!commitFailed) {

			/*notifyLocalSynchsBeforeTransactionCompletion();
			if ( callback ) {
				jdbcContext.notifyLocalSynchsBeforeTransactionCompletion( this );
			}*/

			try {
				rollbackAndResetAutoCommit();
				log.debug("rolled back JDBC Connection");
				rolledBack = true;
				notifyLocalSynchsAfterTransactionCompletion(Status.STATUS_ROLLEDBACK);
			}
			catch (SQLException e) {
				log.error("JDBC rollback failed", e);
				notifyLocalSynchsAfterTransactionCompletion(Status.STATUS_UNKNOWN);
				throw new TransactionException("JDBC rollback failed", e);
			}
			finally {
				if ( callback ) {
					jdbcContext.afterTransactionCompletion( false, this );
				}
				closeIfRequired();
			}
		}
	
private voidrollbackAndResetAutoCommit()

		try {
			jdbcContext.connection().rollback();
		}
		finally {
			toggleAutoCommit();
		}
	
public voidsetTimeout(int seconds)

		timeout = seconds;
	
private voidtoggleAutoCommit()

		try {
			if (toggleAutoCommit) {
				log.debug("re-enabling autocommit");
				jdbcContext.connection().setAutoCommit( true );
			}
		}
		catch (Exception sqle) {
			log.error("Could not toggle autocommit", sqle);
			//swallow it (the transaction _was_ successful or successfully rolled back)
		}
	
public booleanwasCommitted()

		return committed;
	
public booleanwasRolledBack()

		return rolledBack;