org.hibernate.resource.transaction.backend.jta.internal.DdlTransactionIsolatorJtaImpl Maven / Gradle / Ivy
/*
* 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.resource.transaction.backend.jta.internal;
import java.sql.Connection;
import java.sql.SQLException;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import org.hibernate.HibernateException;
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
import org.hibernate.resource.transaction.spi.DdlTransactionIsolator;
import org.hibernate.tool.schema.internal.exec.JdbcContext;
import org.jboss.logging.Logger;
/**
* DdlExecutor for use in JTA environments
*
* @author Steve Ebersole
*/
public class DdlTransactionIsolatorJtaImpl implements DdlTransactionIsolator {
private static final Logger log = Logger.getLogger( DdlTransactionIsolatorJtaImpl.class );
private final JdbcContext jdbcContext;
private Transaction suspendedTransaction;
private Connection jdbcConnection;
public DdlTransactionIsolatorJtaImpl(JdbcContext jdbcContext) {
this.jdbcContext = jdbcContext;
try {
final JtaPlatform jtaPlatform = jdbcContext.getServiceRegistry().getService( JtaPlatform.class );
log.tracef( "DdlTransactionIsolatorJtaImpl#prepare: JtaPlatform -> %s", jtaPlatform );
final TransactionManager tm = jtaPlatform.retrieveTransactionManager();
if ( tm == null ) {
throw new HibernateException(
"DdlTransactionIsolatorJtaImpl could not locate TransactionManager to suspend any current transaction; " +
"base JtaPlatform impl (" + jtaPlatform.toString() + ")?"
);
}
log.tracef( "DdlTransactionIsolatorJtaImpl#prepare: TransactionManager -> %s", tm );
this.suspendedTransaction = tm.suspend();
log.tracef( "DdlTransactionIsolatorJtaImpl#prepare: suspended Transaction -> %s", this.suspendedTransaction );
}
catch (SystemException e) {
throw new HibernateException( "Unable to suspend current JTA transaction in preparation for DDL execution" );
}
try {
this.jdbcConnection = jdbcContext.getJdbcConnectionAccess().obtainConnection();
}
catch (SQLException e) {
throw jdbcContext.getSqlExceptionHelper().convert( e, "Unable to open JDBC Connection for DDL execution" );
}
try {
jdbcConnection.setAutoCommit( true );
}
catch (SQLException e) {
throw jdbcContext.getSqlExceptionHelper().convert( e, "Unable set JDBC Connection for DDL execution to autocommit" );
}
}
@Override
public JdbcContext getJdbcContext() {
return jdbcContext;
}
@Override
public void prepare() {
}
@Override
public Connection getIsolatedConnection() {
return jdbcConnection;
}
@Override
public void release() {
if ( jdbcConnection != null ) {
try {
jdbcContext.getJdbcConnectionAccess().releaseConnection( jdbcConnection );
}
catch (SQLException e) {
throw jdbcContext.getSqlExceptionHelper().convert( e, "Unable to release JDBC Connection used for DDL execution" );
}
}
if ( suspendedTransaction != null ) {
try {
jdbcContext.getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().resume( suspendedTransaction );
}
catch (Exception e) {
throw new HibernateException( "Unable to resume JTA transaction after DDL execution" );
}
}
}
}