HHH-5949 - Migrate, complete and integrate TransactionFactory as a service

This commit is contained in:
Steve Ebersole 2011-03-06 08:46:57 -06:00
parent 0816d00e59
commit 56d242acdf
14 changed files with 106 additions and 273 deletions

View File

@ -70,7 +70,7 @@ libraries = [
atomikos: 'com.atomikos:transactions-jdbc:3.7.0',
junit: 'junit:junit:3.8.2',
testng: 'org.testng:testng:5.8:jdk15',
jpa_modelgen: 'org.hibernate:hibernate-jpamodelgen:1.1.0.Final',
jpa_modelgen: 'org.hibernate:hibernate-jpamodelgen:1.1.1.Final',
shrinkwrap_api: 'org.jboss.shrinkwrap:shrinkwrap-api:1.0.0-alpha-6',
shrinkwrap: 'org.jboss.shrinkwrap:shrinkwrap-impl-base:1.0.0-alpha-6'
]

View File

@ -149,8 +149,7 @@ public class TransactionCoordinatorImpl implements TransactionCoordinator {
@Override
@SuppressWarnings( {"unchecked"})
public boolean isTransactionInProgress() {
return getTransaction().isActive() &&
transactionFactory().getJoinStatus( this, getTransaction() ) == JoinStatus.JOINED;
return getTransaction().isActive() && getTransaction().getJoinStatus() == JoinStatus.JOINED;
}
@Override
@ -278,7 +277,7 @@ public class TransactionCoordinatorImpl implements TransactionCoordinator {
@Override
@SuppressWarnings( {"unchecked"})
public boolean isTransactionJoined() {
return transactionFactory().getJoinStatus( this, currentHibernateTransaction ) == JoinStatus.JOINED;
return currentHibernateTransaction != null && currentHibernateTransaction.getJoinStatus() == JoinStatus.JOINED;
}
public void setRollbackOnly() {

View File

@ -55,17 +55,8 @@ public final class JdbcTransactionFactory implements TransactionFactory<JdbcTran
return false;
}
@Override
public boolean isJoinableJtaTransaction(TransactionCoordinator transactionCoordinator, JdbcTransaction transaction) {
return false;
}
@Override
public JoinStatus getJoinStatus(TransactionCoordinator transactionCoordinator, JdbcTransaction transaction) {
return transaction.getJoinStatus();
}
}

View File

@ -47,6 +47,8 @@ import javax.transaction.TransactionManager;
* @author Steve Ebersole
*/
public class CMTTransaction extends AbstractTransactionImpl {
private JoinStatus joinStatus = JoinStatus.NOT_JOINED;
protected CMTTransaction(TransactionCoordinator transactionCoordinator) {
super( transactionCoordinator );
}
@ -133,22 +135,39 @@ public class CMTTransaction extends AbstractTransactionImpl {
}
}
@Override
public void markForJoin() {
joinStatus = JoinStatus.MARKED_FOR_JOINED;
}
@Override
public void join() {
// todo : implement method body
if ( joinStatus != JoinStatus.MARKED_FOR_JOINED ) {
return;
}
if ( JtaStatusHelper.isActive( transactionManager() ) ) {
joinStatus = JoinStatus.JOINED;
// register synchronization if needed
transactionCoordinator().pulse();
}
else {
joinStatus = JoinStatus.NOT_JOINED;
}
}
@Override
public void resetJoinStatus() {
// todo : implement method body
joinStatus = JoinStatus.NOT_JOINED;
}
boolean isJoinable() {
return JtaStatusHelper.isActive( transactionManager() );
return ( joinStatus == JoinStatus.JOINED || joinStatus == JoinStatus.MARKED_FOR_JOINED ) &&
JtaStatusHelper.isActive( transactionManager() );
}
@Override
public JoinStatus getJoinStatus() {
return isJoinable() ? JoinStatus.JOINED : JoinStatus.NOT_JOINED;
return joinStatus;
}
}

View File

@ -25,7 +25,6 @@ package org.hibernate.engine.transaction.internal.jta;
import org.hibernate.ConnectionReleaseMode;
import org.hibernate.TransactionException;
import org.hibernate.engine.transaction.spi.JoinStatus;
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
import org.hibernate.engine.transaction.spi.TransactionFactory;
@ -65,8 +64,7 @@ public class CMTTransactionFactory implements TransactionFactory<CMTTransaction
.getTransactionContext()
.getTransactionEnvironment()
.getJtaPlatform()
.retrieveTransactionManager()
.getStatus();
.getCurrentStatus();
return JtaStatusHelper.isActive( status );
}
catch( SystemException se ) {
@ -74,10 +72,4 @@ public class CMTTransactionFactory implements TransactionFactory<CMTTransaction
}
}
@Override
public JoinStatus getJoinStatus(TransactionCoordinator transactionCoordinator, CMTTransaction transaction) {
return null; // todo : implement method body
}
}

View File

@ -100,9 +100,4 @@ public class JtaTransactionFactory implements TransactionFactory<JtaTransaction>
}
}
@Override
public JoinStatus getJoinStatus(TransactionCoordinator transactionCoordinator, JtaTransaction transaction) {
return null; // todo : implement method body
}
}

View File

@ -225,7 +225,7 @@ public abstract class AbstractTransactionImpl implements TransactionImplementor
}
@Override
public void resetJoinStatus() {
public void markForJoin() {
// generally speaking this is no-op
}
@ -234,4 +234,8 @@ public abstract class AbstractTransactionImpl implements TransactionImplementor
// generally speaking this is no-op
}
@Override
public void resetJoinStatus() {
// generally speaking this is no-op
}
}

View File

@ -87,8 +87,6 @@ public interface TransactionCoordinator extends Serializable {
* Is the underlying transaction already joined?
*
* @return {@literal true} if the underlying transaction is already joined; {@literal false} otherwise.
*
* @see TransactionFactory#getJoinStatus(TransactionCoordinator, TransactionImplementor)
*/
public boolean isTransactionJoined();

View File

@ -72,16 +72,6 @@ public interface TransactionFactory<T extends TransactionImplementor> extends Se
*/
public boolean isJoinableJtaTransaction(TransactionCoordinator transactionCoordinator, T transaction);
/**
* Retrieve the current join status of the Hibernate transaction
*
* @param transactionCoordinator The transaction coordinator
* @param transaction The current Hibernate transaction
*
* @return The join status.
*/
public JoinStatus getJoinStatus(TransactionCoordinator transactionCoordinator, T transaction);
/**
* Get the default connection release mode.
*

View File

@ -45,6 +45,11 @@ public interface TransactionImplementor extends Transaction {
*/
public JoinStatus getJoinStatus();
/**
* Mark a transaction as joinable
*/
public void markForJoin();
/**
* Perform a join to the underlying transaction
*/

View File

@ -995,15 +995,18 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
}
final SessionImplementor session = (SessionImplementor) getSession();
session.getTransactionCoordinator().pulse();
final TransactionCoordinator transactionCoordinator = session.getTransactionCoordinator();
final TransactionImplementor transaction = transactionCoordinator.getTransaction();
transaction.markForJoin();
transactionCoordinator.pulse();
log.debug( "Looking for a JTA transaction to join" );
if ( ! session.getTransactionCoordinator().isTransactionJoinable() ) {
if ( ! transactionCoordinator.isTransactionJoinable() ) {
log.warn( "Cannot join transaction: do not override {}", Environment.TRANSACTION_STRATEGY );
}
try {
final TransactionImplementor transaction = session.getTransactionCoordinator().getTransaction();
if ( transaction.getJoinStatus() == JoinStatus.JOINED ) {
log.debug( "Transaction already joined" );
@ -1026,7 +1029,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
}
// register behavior changes
SynchronizationCallbackCoordinator callbackCoordinator = session.getTransactionCoordinator().getSynchronizationCallbackCoordinator();
SynchronizationCallbackCoordinator callbackCoordinator = transactionCoordinator.getSynchronizationCallbackCoordinator();
callbackCoordinator.setManagedFlushChecker( new ManagedFlushCheckerImpl() );
callbackCoordinator.setExceptionMapper( new CallbackExceptionMapperImpl() );
callbackCoordinator.setAfterCompletionAction( new AfterCompletionActionImpl( session, transactionType ) );

View File

@ -1,9 +1,10 @@
// $Id$
/*
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, Red Hat Inc. 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.
* distributed under license by Red Hat Inc.
*
* 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
@ -22,6 +23,63 @@
*/
package org.hibernate.ejb;
import org.dom4j.Element;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.MappingException;
import org.hibernate.MappingNotFoundException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.cfg.annotations.reflection.XMLContext;
import org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider;
import org.hibernate.ejb.instrument.InterceptFieldClassFileTransformer;
import org.hibernate.ejb.packaging.JarVisitorFactory;
import org.hibernate.ejb.packaging.NamedInputStream;
import org.hibernate.ejb.packaging.NativeScanner;
import org.hibernate.ejb.packaging.PersistenceMetadata;
import org.hibernate.ejb.packaging.PersistenceXmlLoader;
import org.hibernate.ejb.packaging.Scanner;
import org.hibernate.ejb.util.ConfigurationHelper;
import org.hibernate.ejb.util.LogHelper;
import org.hibernate.ejb.util.NamingHelper;
import org.hibernate.engine.FilterDefinition;
import org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory;
import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory;
import org.hibernate.event.EventListeners;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.internal.util.xml.MappingReader;
import org.hibernate.internal.util.xml.OriginImpl;
import org.hibernate.internal.util.xml.XmlDocument;
import org.hibernate.mapping.AuxiliaryDatabaseObject;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.secure.JACCConfiguration;
import org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator;
import org.hibernate.service.spi.ServiceRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.naming.BinaryRefAddr;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityNotFoundException;
import javax.persistence.MappedSuperclass;
import javax.persistence.PersistenceException;
import javax.persistence.spi.PersistenceUnitInfo;
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
@ -44,63 +102,6 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import javax.naming.BinaryRefAddr;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityNotFoundException;
import javax.persistence.MappedSuperclass;
import javax.persistence.PersistenceException;
import javax.persistence.spi.PersistenceUnitInfo;
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.MappingException;
import org.hibernate.MappingNotFoundException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.cfg.annotations.reflection.XMLContext;
import org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider;
import org.hibernate.ejb.instrument.InterceptFieldClassFileTransformer;
import org.hibernate.ejb.packaging.JarVisitorFactory;
import org.hibernate.ejb.packaging.NamedInputStream;
import org.hibernate.ejb.packaging.NativeScanner;
import org.hibernate.ejb.packaging.PersistenceMetadata;
import org.hibernate.ejb.packaging.PersistenceXmlLoader;
import org.hibernate.ejb.packaging.Scanner;
import org.hibernate.ejb.transaction.JoinableCMTTransactionFactory;
import org.hibernate.ejb.util.ConfigurationHelper;
import org.hibernate.ejb.util.LogHelper;
import org.hibernate.ejb.util.NamingHelper;
import org.hibernate.engine.FilterDefinition;
import org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory;
import org.hibernate.event.EventListeners;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.internal.util.xml.OriginImpl;
import org.hibernate.internal.util.xml.XmlDocument;
import org.hibernate.mapping.AuxiliaryDatabaseObject;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.secure.JACCConfiguration;
import org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator;
import org.hibernate.service.spi.ServiceRegistry;
import org.hibernate.internal.util.xml.MappingReader;
/**
* Allow a fine tuned configuration of an EJB 3.0 EntityManagerFactory
@ -1241,7 +1242,7 @@ public class Ejb3Configuration implements Serializable, Referenceable {
);
if ( ! hasTxStrategy && transactionType == PersistenceUnitTransactionType.JTA ) {
preparedProperties.setProperty(
Environment.TRANSACTION_STRATEGY, JoinableCMTTransactionFactory.class.getName()
Environment.TRANSACTION_STRATEGY, CMTTransactionFactory.class.getName()
);
}
else if ( ! hasTxStrategy && transactionType == PersistenceUnitTransactionType.RESOURCE_LOCAL ) {

View File

@ -1,96 +0,0 @@
/*
* Copyright (c) 2009, 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.ejb.transaction;
import org.hibernate.HibernateException;
import org.hibernate.engine.transaction.internal.jta.CMTTransaction;
import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
import org.hibernate.engine.transaction.spi.JoinStatus;
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
/**
* Implements a joinable transaction. Until the transaction is marked for joined, the TM.isTransactionInProgress()
* must return false
*
* @author Emmanuel Bernard
* @author Steve Ebersole
*/
public class JoinableCMTTransaction extends CMTTransaction {
private JoinStatus joinStatus = JoinStatus.NOT_JOINED;
public JoinableCMTTransaction(TransactionCoordinator transactionCoordinator) {
super( transactionCoordinator );
}
boolean isJoinable() {
return joinStatus == JoinStatus.JOINED && JtaStatusHelper.isActive( transactionManager() );
}
public JoinStatus getJoinStatus() {
return joinStatus;
}
@Override
public void join() {
if ( joinStatus == JoinStatus.MARKED_FOR_JOINED ) {
if ( JtaStatusHelper.isActive( transactionManager() ) ) {
joinStatus = JoinStatus.JOINED;
// register synchronization if needed
transactionCoordinator().pulse();
}
else {
joinStatus = JoinStatus.NOT_JOINED;
}
}
}
@Override
public void resetJoinStatus() {
joinStatus = JoinStatus.NOT_JOINED;
}
@Override
public void begin() throws HibernateException {
super.begin();
joinStatus = JoinStatus.JOINED;
}
@Override
public void commit() throws HibernateException {
/* this method is not supposed to be called
* it breaks the flushBeforeCompletion flag optimization
* regarding flushing skip.
* In its current form, it will generate too much flush() calls
*/
super.commit();
}
public JoinStatus getStatus() {
return joinStatus;
}
public void resetStatus() {
joinStatus = JoinStatus.NOT_JOINED;
}
}

View File

@ -1,68 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009-2011, Red Hat Inc. 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 Inc.
*
* 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.ejb.transaction;
import org.hibernate.ConnectionReleaseMode;
import org.hibernate.engine.transaction.spi.JoinStatus;
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
import org.hibernate.engine.transaction.spi.TransactionFactory;
/**
* A transaction is in progress if the underlying JTA tx is in progress and if the Tx is marked as
* MARKED_FOR_JOINED
*
* @author Emmanuel Bernard
* @author Steve Ebersole
*/
public class JoinableCMTTransactionFactory implements TransactionFactory<JoinableCMTTransaction> {
@Override
public boolean compatibleWithJtaSynchronization() {
return true;
}
@Override
public boolean canBeDriver() {
return false;
}
@Override
public JoinableCMTTransaction createTransaction(TransactionCoordinator transactionCoordinator) {
return new JoinableCMTTransaction( transactionCoordinator );
}
@Override
public boolean isJoinableJtaTransaction(TransactionCoordinator transactionCoordinator, JoinableCMTTransaction transaction) {
return transaction.isJoinable();
}
@Override
public JoinStatus getJoinStatus(TransactionCoordinator transactionCoordinator, JoinableCMTTransaction transaction) {
return transaction.getJoinStatus();
}
@Override
public ConnectionReleaseMode getDefaultReleaseMode() {
return ConnectionReleaseMode.AFTER_STATEMENT;
}
}