HHH-9756 - NPE in JtaTransactionCoordinatorImpl#explicitJoin() after previously executed transaction

This commit is contained in:
Steve Ebersole 2015-05-07 14:59:25 -05:00
parent 165f037bad
commit 21abf08452
19 changed files with 1521 additions and 10 deletions

View File

@ -34,7 +34,7 @@ import org.hibernate.internal.CoreLogging;
import org.hibernate.resource.transaction.TransactionCoordinator;
import org.hibernate.resource.transaction.spi.TransactionStatus;
import static org.hibernate.resource.transaction.TransactionCoordinator.LocalInflow;
import static org.hibernate.resource.transaction.TransactionCoordinator.TransactionDriver;
/**
* @author Andrea Boriero
@ -43,7 +43,7 @@ public class TransactionImpl implements Transaction {
private static final Logger LOG = CoreLogging.logger( TransactionImpl.class );
private final TransactionCoordinator transactionCoordinator;
private final LocalInflow transactionDriverControl;
private final TransactionDriver transactionDriverControl;
private boolean valid = true;

View File

@ -58,7 +58,7 @@ public interface TransactionCoordinator {
*
* @return The control delegate.
*/
public LocalInflow getTransactionDriverControl();
public TransactionDriver getTransactionDriverControl();
/**
* Get access to the local registry of Synchronization instances
@ -119,7 +119,7 @@ public interface TransactionCoordinator {
*
* @author Steve Ebersole
*/
public interface LocalInflow {
public interface TransactionDriver {
/**
* Begin the physical transaction
*/

View File

@ -83,7 +83,7 @@ public class JdbcResourceLocalTransactionCoordinatorImpl implements TransactionC
}
@Override
public LocalInflow getTransactionDriverControl() {
public TransactionDriver getTransactionDriverControl() {
// Again, this PhysicalTransactionDelegate will act as the bridge from the local transaction back into the
// coordinator. We lazily build it as we invalidate each delegate after each transaction (a delegate is
// valid for just one transaction)
@ -200,7 +200,7 @@ public class JdbcResourceLocalTransactionCoordinatorImpl implements TransactionC
* The delegate bridging between the local (application facing) transaction and the "physical" notion of a
* transaction via the JDBC Connection.
*/
public class TransactionDriverControlImpl implements LocalInflow {
public class TransactionDriverControlImpl implements TransactionDriver {
private final JdbcResourceTransaction jdbcResourceTransaction;
private boolean invalid;

View File

@ -1,6 +1,7 @@
package org.hibernate.resource.transaction.backend.jta.internal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.transaction.Status;
import javax.transaction.TransactionManager;
@ -83,6 +84,32 @@ public class JtaTransactionCoordinatorImpl implements TransactionCoordinator, Sy
pulse();
}
public JtaTransactionCoordinatorImpl(
TransactionCoordinatorBuilder transactionCoordinatorBuilder,
TransactionCoordinatorOwner owner,
boolean autoJoinTransactions,
JtaPlatform jtaPlatform,
boolean preferUserTransactions,
boolean performJtaThreadTracking,
TransactionObserver... observers) {
this.observers = new ArrayList<TransactionObserver>();
this.transactionCoordinatorBuilder = transactionCoordinatorBuilder;
this.transactionCoordinatorOwner = owner;
this.autoJoinTransactions = autoJoinTransactions;
this.jtaPlatform = jtaPlatform;
this.preferUserTransactions = preferUserTransactions;
this.performJtaThreadTracking = performJtaThreadTracking;
if ( observers != null ) {
Collections.addAll( this.observers, observers );
}
synchronizationRegistered = false;
pulse();
}
public SynchronizationCallbackCoordinator getSynchronizationCallbackCoordinator() {
if ( callbackCoordinator == null ) {
callbackCoordinator = performJtaThreadTracking
@ -133,7 +160,7 @@ public class JtaTransactionCoordinatorImpl implements TransactionCoordinator, Sy
return;
}
if ( physicalTransactionDelegate.getStatus() != TransactionStatus.ACTIVE ) {
if ( getTransactionDriverControl().getStatus() != TransactionStatus.ACTIVE ) {
return;
}
@ -161,7 +188,7 @@ public class JtaTransactionCoordinatorImpl implements TransactionCoordinator, Sy
}
@Override
public LocalInflow getTransactionDriverControl() {
public TransactionDriver getTransactionDriverControl() {
if ( physicalTransactionDelegate == null ) {
physicalTransactionDelegate = makePhysicalTransactionDelegate();
}
@ -320,7 +347,7 @@ public class JtaTransactionCoordinatorImpl implements TransactionCoordinator, Sy
* local transaction ({@link org.hibernate.Transaction} to callback into this
* TransactionCoordinator for the purpose of driving the underlying JTA transaction.
*/
public class TransactionDriverControlImpl implements LocalInflow {
public class TransactionDriverControlImpl implements TransactionDriver {
private final JtaTransactionAdapter jtaTransactionAdapter;
private boolean invalid;

View File

@ -37,7 +37,7 @@
* The local transaction is the idea of transactionality exposed to the application (as
* {@link org.hibernate.Transaction}) as a means to control the underlying transaction. That
* control flows from the {@link org.hibernate.Transaction} into the TransactionCoordinator
* through the {@link org.hibernate.resource.transaction.TransactionCoordinator.LocalInflow} it exposes.
* through the {@link org.hibernate.resource.transaction.TransactionCoordinator.TransactionDriver} it exposes.
*
* <h2>Physical transaction</h2>
*

View File

@ -0,0 +1,69 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2015, 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.test.resource.common;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.SQLException;
import java.util.Properties;
import org.hibernate.HibernateException;
import org.hibernate.cfg.AvailableSettings;
/**
* @author Steve Ebersole
*/
public class DatabaseConnectionInfo {
/**
* Singleton access
*/
public static final DatabaseConnectionInfo INSTANCE = new DatabaseConnectionInfo();
public static final String DRIVER = "org.h2.Driver";
public static final String URL = "jdbc:h2:mem:hibernate-core";
public static final String USER = "hibernate";
public static final String PASS = "hibernate";
public Properties createDriverManagerProperties() {
Properties props = new Properties();
props.setProperty( AvailableSettings.USER, USER );
props.setProperty( AvailableSettings.PASS, PASS );
return props;
}
private Driver driver;
public Connection makeConnection() throws SQLException {
if ( driver == null ) {
try {
driver = (Driver) Class.forName( DRIVER ).newInstance();
}
catch (Exception e) {
throw new HibernateException( "Unable to load JDBC Driver [" + DRIVER + "]", e );
}
}
return driver.connect( URL, createDriverManagerProperties() );
}
}

View File

@ -0,0 +1,69 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2015, 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.test.resource.common;
import javax.transaction.Status;
import javax.transaction.Synchronization;
/**
* @author Steve Ebersole
*/
public class SynchronizationCollectorImpl implements Synchronization {
private int beforeCompletionCount;
private int successfulCompletionCount;
private int failedCompletionCount;
@Override
public void beforeCompletion() {
beforeCompletionCount++;
}
@Override
public void afterCompletion(int status) {
if ( status == Status.STATUS_COMMITTED ) {
successfulCompletionCount++;
}
else {
failedCompletionCount++;
}
}
public int getBeforeCompletionCount() {
return beforeCompletionCount;
}
public int getSuccessfulCompletionCount() {
return successfulCompletionCount;
}
public int getFailedCompletionCount() {
return failedCompletionCount;
}
public void reset() {
beforeCompletionCount = 0;
successfulCompletionCount = 0;
failedCompletionCount = 0;
}
}

View File

@ -0,0 +1,53 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2015, 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.test.resource.common;
import javax.transaction.Synchronization;
/**
* @author Steve Ebersole
*/
public class SynchronizationErrorImpl implements Synchronization {
private final boolean errorOnBefore;
private final boolean errorOnAfter;
public SynchronizationErrorImpl(boolean errorOnBefore, boolean errorOnAfter) {
this.errorOnBefore = errorOnBefore;
this.errorOnAfter = errorOnAfter;
}
@Override
public void beforeCompletion() {
if ( errorOnBefore ) {
throw new RuntimeException( "throwing requested error on beforeCompletion" );
}
}
@Override
public void afterCompletion(int status) {
if ( errorOnAfter ) {
throw new RuntimeException( "throwing requested error on afterCompletion" );
}
}
}

View File

@ -0,0 +1,140 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2015, 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.test.resource.transaction;
import javax.transaction.Status;
import javax.transaction.Synchronization;
import org.hibernate.resource.transaction.LocalSynchronizationException;
import org.hibernate.resource.transaction.NullSynchronizationException;
import org.hibernate.resource.transaction.internal.SynchronizationRegistryStandardImpl;
import org.hibernate.test.resource.common.SynchronizationCollectorImpl;
import org.hibernate.test.resource.common.SynchronizationErrorImpl;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
/**
* Unit tests for SynchronizationRegistryStandardImpl.
*
* @author Steve Ebersole
*/
public class SynchronizationRegistryStandardImplTests {
@Test
public void basicUsageTests() {
final SynchronizationRegistryStandardImpl registry = new SynchronizationRegistryStandardImpl();
try {
registry.registerSynchronization( null );
fail( "Was expecting NullSynchronizationException, but call succeeded" );
}
catch (NullSynchronizationException expected) {
// expected behavior
}
catch (Exception e) {
fail( "Was expecting NullSynchronizationException, but got " + e.getClass().getName() );
}
final SynchronizationCollectorImpl synchronization = new SynchronizationCollectorImpl();
assertEquals( 0, registry.getNumberOfRegisteredSynchronizations() );
registry.registerSynchronization( synchronization );
assertEquals( 1, registry.getNumberOfRegisteredSynchronizations() );
registry.registerSynchronization( synchronization );
assertEquals( 1, registry.getNumberOfRegisteredSynchronizations() );
assertEquals( 0, synchronization.getBeforeCompletionCount() );
assertEquals( 0, synchronization.getSuccessfulCompletionCount() );
assertEquals( 0, synchronization.getFailedCompletionCount() );
{
registry.notifySynchronizationsBeforeTransactionCompletion();
assertEquals( 1, synchronization.getBeforeCompletionCount() );
assertEquals( 0, synchronization.getSuccessfulCompletionCount() );
assertEquals( 0, synchronization.getFailedCompletionCount() );
registry.notifySynchronizationsAfterTransactionCompletion( Status.STATUS_COMMITTED );
assertEquals( 1, synchronization.getBeforeCompletionCount() );
assertEquals( 1, synchronization.getSuccessfulCompletionCount() );
assertEquals( 0, synchronization.getFailedCompletionCount() );
}
// after completion should clear registered synchronizations
assertEquals( 0, registry.getNumberOfRegisteredSynchronizations() );
// reset the sync
synchronization.reset();
assertEquals( 0, synchronization.getBeforeCompletionCount() );
assertEquals( 0, synchronization.getSuccessfulCompletionCount() );
assertEquals( 0, synchronization.getFailedCompletionCount() );
// re-register it
registry.registerSynchronization( synchronization );
assertEquals( 1, registry.getNumberOfRegisteredSynchronizations() );
{
registry.notifySynchronizationsAfterTransactionCompletion( Status.STATUS_ROLLEDBACK );
assertEquals( 0, synchronization.getBeforeCompletionCount() );
assertEquals( 0, synchronization.getSuccessfulCompletionCount() );
assertEquals( 1, synchronization.getFailedCompletionCount() );
// after completion should clear registered synchronizations
assertEquals( 0, registry.getNumberOfRegisteredSynchronizations() );
}
}
@Test
public void testUserSynchronizationExceptions() {
// exception in beforeCompletion
SynchronizationRegistryStandardImpl registry = new SynchronizationRegistryStandardImpl();
Synchronization synchronization = new SynchronizationErrorImpl( true, false );
registry.registerSynchronization( synchronization );
try {
registry.notifySynchronizationsBeforeTransactionCompletion();
fail( "Expecting LocalSynchronizationException, but call succeeded" );
}
catch (LocalSynchronizationException expected) {
// expected
}
catch (Exception e) {
fail( "Was expecting LocalSynchronizationException, but got " + e.getClass().getName() );
}
// exception in beforeCompletion
registry.clearSynchronizations();
registry = new SynchronizationRegistryStandardImpl();
synchronization = new SynchronizationErrorImpl( false, true );
registry.registerSynchronization( synchronization );
try {
registry.notifySynchronizationsAfterTransactionCompletion( Status.STATUS_COMMITTED );
fail( "Expecting LocalSynchronizationException, but call succeeded" );
}
catch (LocalSynchronizationException expected) {
// expected
}
catch (Exception e) {
fail( "Was expecting LocalSynchronizationException, but got " + e.getClass().getName() );
}
}
}

View File

@ -0,0 +1,70 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2015, 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.test.resource.transaction.jdbc;
import org.hibernate.resource.transaction.TransactionCoordinator;
import org.hibernate.resource.transaction.TransactionCoordinatorBuilder;
import org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorBuilderImpl;
import org.hibernate.test.resource.common.SynchronizationCollectorImpl;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* @author Steve Ebersole
*/
public class BasicJdbcTransactionTests {
@Test
public void basicUsageTest() throws Exception {
final TransactionCoordinatorOwnerTestingImpl owner = new TransactionCoordinatorOwnerTestingImpl();
final JdbcResourceLocalTransactionCoordinatorBuilderImpl transactionCoordinatorBuilder =
new JdbcResourceLocalTransactionCoordinatorBuilderImpl();
final TransactionCoordinator transactionCoordinator = transactionCoordinatorBuilder.buildTransactionCoordinator(
owner,
new TransactionCoordinatorBuilder.TransactionCoordinatorOptions() {
@Override
public boolean shouldAutoJoinTransaction() {
return false;
}
}
);
SynchronizationCollectorImpl sync = new SynchronizationCollectorImpl();
transactionCoordinator.getLocalSynchronizations().registerSynchronization( sync );
transactionCoordinator.getTransactionDriverControl().begin();
assertEquals( 0, sync.getBeforeCompletionCount() );
assertEquals( 0, sync.getSuccessfulCompletionCount() );
assertEquals( 0, sync.getFailedCompletionCount() );
transactionCoordinator.getTransactionDriverControl().commit();
assertEquals( 1, sync.getBeforeCompletionCount() );
assertEquals( 1, sync.getSuccessfulCompletionCount() );
assertEquals( 0, sync.getFailedCompletionCount() );
}
}

View File

@ -0,0 +1,37 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2015, 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.test.resource.transaction.jdbc;
import org.hibernate.resource.jdbc.internal.LogicalConnectionProvidedImpl;
import org.hibernate.test.resource.common.DatabaseConnectionInfo;
/**
* @author Steve Ebersole
*/
public class LogicalConnectionTestingImpl extends LogicalConnectionProvidedImpl {
public LogicalConnectionTestingImpl() throws Exception {
super( DatabaseConnectionInfo.INSTANCE.makeConnection() );
}
}

View File

@ -0,0 +1,136 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2015, 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.test.resource.transaction.jdbc;
import org.hibernate.HibernateException;
import org.hibernate.resource.jdbc.spi.JdbcSessionOwner;
import org.hibernate.resource.transaction.backend.jdbc.spi.JdbcResourceTransaction;
import org.hibernate.resource.transaction.backend.jdbc.spi.JdbcResourceTransactionAccess;
import org.hibernate.resource.transaction.spi.TransactionCoordinatorOwner;
import org.jboss.logging.Logger;
/**
* @author Steve Ebersole
*/
public class TransactionCoordinatorOwnerTestingImpl
implements TransactionCoordinatorOwner, JdbcResourceTransactionAccess {
private static final Logger log = Logger.getLogger( TransactionCoordinatorOwnerTestingImpl.class );
private LogicalConnectionTestingImpl logicalConnection;
private boolean active;
private int beginCount;
private int beforeCompletionCount;
private int successfulCompletionCount;
private int failedCompletionCount;
public TransactionCoordinatorOwnerTestingImpl() {
this( true );
}
public TransactionCoordinatorOwnerTestingImpl(boolean active) {
this.active = active;
try {
this.logicalConnection = new LogicalConnectionTestingImpl();
}
catch (Exception e) {
throw new HibernateException( "Could not create logical connection", e );
}
}
@Override
public JdbcResourceTransaction getResourceLocalTransaction() {
return logicalConnection;
}
public int getBeforeCompletionCount() {
return beforeCompletionCount;
}
public int getSuccessfulCompletionCount() {
return successfulCompletionCount;
}
public int getFailedCompletionCount() {
return failedCompletionCount;
}
public void reset() {
beginCount = 0;
beforeCompletionCount = 0;
successfulCompletionCount = 0;
failedCompletionCount = 0;
}
public void deactivate() {
active = false;
}
@Override
public boolean isActive() {
return active;
}
@Override
public void afterTransactionBegin() {
log.debug( "#afterTransactionBegin called" );
beginCount++;
}
@Override
public void beforeTransactionCompletion() {
log.debug( "#beforeTransactionCompletion called" );
beforeCompletionCount++;
}
@Override
public void afterTransactionCompletion(boolean successful) {
log.debug( "#afterTransactionCompletion called" );
if ( successful ) {
successfulCompletionCount++;
}
else {
failedCompletionCount++;
}
}
@Override
public JdbcSessionOwner getJdbcSessionOwner() {
return null;
}
@Override
public void setTransactionTimeOut(int seconds) {
}
@Override
public void flushBeforeTransactionCompletion() {
}
}

View File

@ -0,0 +1,357 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2015, 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.test.resource.transaction.jta;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.TransactionManager;
import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorBuilderImpl;
import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl;
import org.hibernate.resource.transaction.backend.jta.internal.synchronization.SynchronizationCallbackCoordinatorTrackingImpl;
import org.hibernate.test.resource.common.SynchronizationCollectorImpl;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* @author Steve Ebersole
*/
public abstract class AbstractBasicJtaTestScenarios {
private final TransactionCoordinatorOwnerTestingImpl owner = new TransactionCoordinatorOwnerTestingImpl();
private JtaTransactionCoordinatorBuilderImpl transactionCoordinatorBuilder = new JtaTransactionCoordinatorBuilderImpl();
protected abstract boolean preferUserTransactions();
public JtaTransactionCoordinatorImpl buildTransactionCoordinator(boolean autoJoin) {
return new JtaTransactionCoordinatorImpl(
transactionCoordinatorBuilder,
owner,
autoJoin,
JtaPlatformStandardTestingImpl.INSTANCE,
preferUserTransactions(),
false
);
}
@Before
@After
public void resetJtaPlatform() throws SystemException {
// make sure the JTA platform is reset back to no active transactions before and after each test
JtaPlatformStandardTestingImpl.INSTANCE.reset();
}
@Test
public void basicBmtUsageTest() throws Exception {
final JtaTransactionCoordinatorImpl transactionCoordinator = buildTransactionCoordinator( true );
// pre conditions
final TransactionManager tm = JtaPlatformStandardTestingImpl.INSTANCE.transactionManager();
assertEquals( Status.STATUS_NO_TRANSACTION, tm.getStatus() );
assertFalse( transactionCoordinator.isSynchronizationRegistered() );
// begin the transaction
transactionCoordinator.getTransactionDriverControl().begin();
assertEquals( Status.STATUS_ACTIVE, tm.getStatus() );
assertTrue( transactionCoordinator.isSynchronizationRegistered() );
// create and add a local Synchronization
SynchronizationCollectorImpl localSync = new SynchronizationCollectorImpl();
transactionCoordinator.getLocalSynchronizations().registerSynchronization( localSync );
// commit the transaction
transactionCoordinator.getTransactionDriverControl().commit();
assertEquals( Status.STATUS_NO_TRANSACTION, tm.getStatus() );
assertFalse( transactionCoordinator.isSynchronizationRegistered() );
assertEquals( 1, localSync.getBeforeCompletionCount() );
assertEquals( 1, localSync.getSuccessfulCompletionCount() );
assertEquals( 0, localSync.getFailedCompletionCount() );
}
@Test
public void rollbackBmtUsageTest() throws Exception {
final JtaTransactionCoordinatorImpl transactionCoordinator = buildTransactionCoordinator( true );
// pre conditions
final TransactionManager tm = JtaPlatformStandardTestingImpl.INSTANCE.transactionManager();
assertEquals( Status.STATUS_NO_TRANSACTION, tm.getStatus() );
assertFalse( transactionCoordinator.isSynchronizationRegistered() );
// begin the transaction
transactionCoordinator.getTransactionDriverControl().begin();
assertEquals( Status.STATUS_ACTIVE, tm.getStatus() );
assertTrue( transactionCoordinator.isSynchronizationRegistered() );
// create and add a local Synchronization
SynchronizationCollectorImpl localSync = new SynchronizationCollectorImpl();
transactionCoordinator.getLocalSynchronizations().registerSynchronization( localSync );
// rollback the transaction
transactionCoordinator.getTransactionDriverControl().rollback();
// post conditions
assertEquals( Status.STATUS_NO_TRANSACTION, tm.getStatus() );
assertFalse( transactionCoordinator.isSynchronizationRegistered() );
assertEquals( 0, localSync.getBeforeCompletionCount() );
assertEquals( 0, localSync.getSuccessfulCompletionCount() );
assertEquals( 1, localSync.getFailedCompletionCount() );
}
@Test
public void basicCmtUsageTest() throws Exception {
// pre conditions
final TransactionManager tm = JtaPlatformStandardTestingImpl.INSTANCE.transactionManager();
assertEquals( Status.STATUS_NO_TRANSACTION, tm.getStatus() );
// begin the transaction
tm.begin();
final JtaTransactionCoordinatorImpl transactionCoordinator = buildTransactionCoordinator( true );
assertEquals( Status.STATUS_ACTIVE, tm.getStatus() );
// NOTE : because of auto-join
assertTrue( transactionCoordinator.isSynchronizationRegistered() );
// create and add a local Synchronization
SynchronizationCollectorImpl localSync = new SynchronizationCollectorImpl();
transactionCoordinator.getLocalSynchronizations().registerSynchronization( localSync );
// commit the transaction
tm.commit();
// post conditions
assertEquals( Status.STATUS_NO_TRANSACTION, tm.getStatus() );
assertFalse( transactionCoordinator.isSynchronizationRegistered() );
assertEquals( 1, localSync.getBeforeCompletionCount() );
assertEquals( 1, localSync.getSuccessfulCompletionCount() );
assertEquals( 0, localSync.getFailedCompletionCount() );
}
@Test
public void basicCmtUsageWithPulseTest() throws Exception {
// pre conditions
final TransactionManager tm = JtaPlatformStandardTestingImpl.INSTANCE.transactionManager();
assertEquals( Status.STATUS_NO_TRANSACTION, tm.getStatus() );
final JtaTransactionCoordinatorImpl transactionCoordinator = buildTransactionCoordinator( true );
// begin the transaction
tm.begin();
assertEquals( Status.STATUS_ACTIVE, tm.getStatus() );
transactionCoordinator.pulse();
// NOTE : because of auto-join
assertTrue( transactionCoordinator.isSynchronizationRegistered() );
transactionCoordinator.pulse();
assertTrue( transactionCoordinator.isSynchronizationRegistered() );
// create and add a local Synchronization
SynchronizationCollectorImpl localSync = new SynchronizationCollectorImpl();
transactionCoordinator.getLocalSynchronizations().registerSynchronization( localSync );
// commit the transaction
tm.commit();
// post conditions
assertEquals( Status.STATUS_NO_TRANSACTION, tm.getStatus() );
assertFalse( transactionCoordinator.isSynchronizationRegistered() );
assertEquals( 1, localSync.getBeforeCompletionCount() );
assertEquals( 1, localSync.getSuccessfulCompletionCount() );
assertEquals( 0, localSync.getFailedCompletionCount() );
}
@Test
public void rollbackCmtUsageTest() throws Exception {
// pre conditions
final TransactionManager tm = JtaPlatformStandardTestingImpl.INSTANCE.transactionManager();
assertEquals( Status.STATUS_NO_TRANSACTION, tm.getStatus() );
// begin the transaction
tm.begin();
assertEquals( Status.STATUS_ACTIVE, tm.getStatus() );
final JtaTransactionCoordinatorImpl transactionCoordinator = buildTransactionCoordinator( true );
// NOTE : because of auto-join
assertTrue( transactionCoordinator.isSynchronizationRegistered() );
// create and add a local Synchronization
SynchronizationCollectorImpl localSync = new SynchronizationCollectorImpl();
transactionCoordinator.getLocalSynchronizations().registerSynchronization( localSync );
// rollback the transaction
tm.rollback();
// post conditions
assertEquals( Status.STATUS_NO_TRANSACTION, tm.getStatus() );
assertFalse( transactionCoordinator.isSynchronizationRegistered() );
assertEquals( 0, localSync.getBeforeCompletionCount() );
assertEquals( 0, localSync.getSuccessfulCompletionCount() );
assertEquals( 1, localSync.getFailedCompletionCount() );
}
@Test
public void explicitJoiningTest() throws Exception {
// pre conditions
final TransactionManager tm = JtaPlatformStandardTestingImpl.INSTANCE.transactionManager();
assertEquals( Status.STATUS_NO_TRANSACTION, tm.getStatus() );
final JtaTransactionCoordinatorImpl transactionCoordinator = buildTransactionCoordinator( false );
// begin the transaction
tm.begin();
assertEquals( Status.STATUS_ACTIVE, tm.getStatus() );
// no auto-join now
assertFalse( transactionCoordinator.isSynchronizationRegistered() );
transactionCoordinator.explicitJoin();
assertTrue( transactionCoordinator.isSynchronizationRegistered() );
// create and add a local Synchronization
SynchronizationCollectorImpl localSync = new SynchronizationCollectorImpl();
transactionCoordinator.getLocalSynchronizations().registerSynchronization( localSync );
// commit the transaction
tm.commit();
// post conditions
assertEquals( Status.STATUS_NO_TRANSACTION, tm.getStatus() );
assertFalse( transactionCoordinator.isSynchronizationRegistered() );
assertEquals( 1, localSync.getBeforeCompletionCount() );
assertEquals( 1, localSync.getSuccessfulCompletionCount() );
assertEquals( 0, localSync.getFailedCompletionCount() );
}
@Test
public void jpaExplicitJoiningTest() throws Exception {
// pre conditions
final TransactionManager tm = JtaPlatformStandardTestingImpl.INSTANCE.transactionManager();
assertEquals( Status.STATUS_NO_TRANSACTION, tm.getStatus() );
// begin the transaction
tm.begin();
assertEquals( Status.STATUS_ACTIVE, tm.getStatus() );
final JtaTransactionCoordinatorImpl transactionCoordinator = buildTransactionCoordinator( false );
// no auto-join now
assertFalse( transactionCoordinator.isSynchronizationRegistered() );
transactionCoordinator.explicitJoin();
assertTrue( transactionCoordinator.isSynchronizationRegistered() );
// create and add a local Synchronization
SynchronizationCollectorImpl localSync = new SynchronizationCollectorImpl();
transactionCoordinator.getLocalSynchronizations().registerSynchronization( localSync );
// commit the transaction
tm.commit();
// post conditions
assertEquals( Status.STATUS_NO_TRANSACTION, tm.getStatus() );
assertFalse( transactionCoordinator.isSynchronizationRegistered() );
assertEquals( 1, localSync.getBeforeCompletionCount() );
assertEquals( 1, localSync.getSuccessfulCompletionCount() );
assertEquals( 0, localSync.getFailedCompletionCount() );
}
@Test
public void assureMultipleJoinCallsNoOp() throws Exception {
// pre conditions
final TransactionManager tm = JtaPlatformStandardTestingImpl.INSTANCE.transactionManager();
assertEquals( Status.STATUS_NO_TRANSACTION, tm.getStatus() );
// begin the transaction
tm.begin();
assertEquals( Status.STATUS_ACTIVE, tm.getStatus() );
final JtaTransactionCoordinatorImpl transactionCoordinator = buildTransactionCoordinator( false );
// no auto-join now
assertFalse( transactionCoordinator.isJoined() );
transactionCoordinator.explicitJoin();
assertTrue( transactionCoordinator.isJoined() );
transactionCoordinator.explicitJoin();
transactionCoordinator.explicitJoin();
transactionCoordinator.explicitJoin();
transactionCoordinator.explicitJoin();
assertTrue( transactionCoordinator.isJoined() );
// create and add a local Synchronization
SynchronizationCollectorImpl localSync = new SynchronizationCollectorImpl();
transactionCoordinator.getLocalSynchronizations().registerSynchronization( localSync );
// commit the transaction
tm.commit();
// post conditions
assertEquals( Status.STATUS_NO_TRANSACTION, tm.getStatus() );
assertFalse( transactionCoordinator.isSynchronizationRegistered() );
assertEquals( 1, localSync.getBeforeCompletionCount() );
assertEquals( 1, localSync.getSuccessfulCompletionCount() );
assertEquals( 0, localSync.getFailedCompletionCount() );
}
@Test
public void basicThreadCheckingUsage() throws Exception {
JtaTransactionCoordinatorImpl transactionCoordinator = new JtaTransactionCoordinatorImpl(
transactionCoordinatorBuilder,
owner,
true,
JtaPlatformStandardTestingImpl.INSTANCE,
preferUserTransactions(),
true
);
// pre conditions
final TransactionManager tm = JtaPlatformStandardTestingImpl.INSTANCE.transactionManager();
assertEquals( Status.STATUS_NO_TRANSACTION, tm.getStatus() );
// begin the transaction
tm.begin();
transactionCoordinator.explicitJoin();
assertEquals(
SynchronizationCallbackCoordinatorTrackingImpl.class,
transactionCoordinator.getSynchronizationCallbackCoordinator().getClass()
);
tm.commit();
assertEquals( Status.STATUS_NO_TRANSACTION, tm.getStatus() );
assertFalse( transactionCoordinator.isJoined() );
tm.begin();
transactionCoordinator.explicitJoin();
assertEquals(
SynchronizationCallbackCoordinatorTrackingImpl.class,
transactionCoordinator.getSynchronizationCallbackCoordinator().getClass()
);
tm.rollback();
}
}

View File

@ -0,0 +1,36 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2015, 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.test.resource.transaction.jta;
import org.hibernate.test.resource.transaction.jta.AbstractBasicJtaTestScenarios;
/**
* @author Steve Ebersole
*/
public class BasicJtaTransactionManagerTests extends AbstractBasicJtaTestScenarios {
@Override
protected boolean preferUserTransactions() {
return false;
}
}

View File

@ -0,0 +1,36 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2015, 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.test.resource.transaction.jta;
import org.hibernate.test.resource.transaction.jta.AbstractBasicJtaTestScenarios;
/**
* @author Steve Ebersole
*/
public class BasicJtaUserTransactionTests extends AbstractBasicJtaTestScenarios {
@Override
protected boolean preferUserTransactions() {
return true;
}
}

View File

@ -0,0 +1,141 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2015, 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.test.resource.transaction.jta;
import org.hibernate.resource.transaction.TransactionCoordinator;
import org.hibernate.resource.transaction.backend.jta.internal.JtaPlatformInaccessibleException;
import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorBuilderImpl;
import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl;
import org.junit.Test;
import static org.junit.Assert.fail;
/**
* @author Steve Ebersole
*/
public class InaccessibleJtaPlatformTests {
private final TransactionCoordinatorOwnerTestingImpl owner = new TransactionCoordinatorOwnerTestingImpl();
private JtaTransactionCoordinatorBuilderImpl transactionCoordinatorBuilder = new JtaTransactionCoordinatorBuilderImpl();
@Test
public void testInaccessibleTransactionManagerHandling() {
// first, have JtaPlatform throw an exception
try {
final JtaPlatformInaccessibleImpl jtaPlatform = new JtaPlatformInaccessibleImpl( true );
final TransactionCoordinator transactionCoordinator = new JtaTransactionCoordinatorImpl(
transactionCoordinatorBuilder,
owner,
true,
jtaPlatform,
false,
false
);
transactionCoordinator.getTransactionDriverControl().begin();
fail( "Expecting JtaPlatformInaccessibleException, but call succeeded" );
}
catch (JtaPlatformInaccessibleException expected) {
// expected condition
}
catch (Exception e) {
fail( "Expecting JtaPlatformInaccessibleException, but got " + e.getClass().getName() );
}
// then, have it return null
try {
final JtaPlatformInaccessibleImpl jtaPlatform = new JtaPlatformInaccessibleImpl( false );
final TransactionCoordinator transactionCoordinator = new JtaTransactionCoordinatorImpl(
transactionCoordinatorBuilder,
owner,
true,
jtaPlatform,
false,
false
);
transactionCoordinator.getTransactionDriverControl().begin();
fail( "Expecting JtaPlatformInaccessibleException, but call succeeded" );
}
catch (JtaPlatformInaccessibleException expected) {
// expected condition
}
catch (Exception e) {
fail( "Expecting JtaPlatformInaccessibleException, but got " + e.getClass().getName() );
}
}
@Test
public void testInaccessibleUserTransactionHandling() {
// first, have JtaPlatform throw an exception
try {
final JtaPlatformInaccessibleImpl jtaPlatform = new JtaPlatformInaccessibleImpl( true );
final TransactionCoordinator transactionCoordinator = new JtaTransactionCoordinatorImpl(
transactionCoordinatorBuilder,
owner,
true,
jtaPlatform,
false,
false
);
transactionCoordinator.getTransactionDriverControl().begin();
fail( "Expecting JtaPlatformInaccessibleException, but call succeeded" );
}
catch (JtaPlatformInaccessibleException expected) {
// expected condition
}
catch (Exception e) {
fail( "Expecting JtaPlatformInaccessibleException, but got " + e.getClass().getName() );
}
// then, have it return null
try {
final JtaPlatformInaccessibleImpl jtaPlatform = new JtaPlatformInaccessibleImpl( false );
final TransactionCoordinator transactionCoordinator = new JtaTransactionCoordinatorImpl(
transactionCoordinatorBuilder,
owner,
true,
jtaPlatform,
false,
false
);
transactionCoordinator.getTransactionDriverControl().begin();
fail( "Expecting JtaPlatformInaccessibleException, but call succeeded" );
}
catch (JtaPlatformInaccessibleException expected) {
// expected condition
}
catch (Exception e) {
fail( "Expecting JtaPlatformInaccessibleException, but got " + e.getClass().getName() );
}
}
}

View File

@ -0,0 +1,90 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2015, 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.test.resource.transaction.jta;
import javax.transaction.Status;
import javax.transaction.Synchronization;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
/**
* JtaPlatform used to test cases when JTA in not available
*
* @author Steve Ebersole
*/
public class JtaPlatformInaccessibleImpl implements JtaPlatform {
private final boolean preferExceptions;
public JtaPlatformInaccessibleImpl(boolean preferExceptions) {
this.preferExceptions = preferExceptions;
}
@Override
public TransactionManager retrieveTransactionManager() {
if ( preferExceptions ) {
throw new JtaPlatformInaccessibleException();
}
return null;
}
@Override
public UserTransaction retrieveUserTransaction() {
if ( preferExceptions ) {
throw new JtaPlatformInaccessibleException();
}
return null;
}
@Override
public Object getTransactionIdentifier(Transaction transaction) {
if ( preferExceptions ) {
throw new JtaPlatformInaccessibleException();
}
return null;
}
@Override
public boolean canRegisterSynchronization() {
return false;
}
@Override
public void registerSynchronization(Synchronization synchronization) {
if ( preferExceptions ) {
throw new JtaPlatformInaccessibleException();
}
}
@Override
public int getCurrentStatus() throws SystemException {
return Status.STATUS_NO_TRANSACTION;
}
public static class JtaPlatformInaccessibleException extends RuntimeException {
}
}

View File

@ -0,0 +1,133 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2015, 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.test.resource.transaction.jta;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.TransactionManager;
import javax.transaction.TransactionSynchronizationRegistry;
import javax.transaction.UserTransaction;
import org.hibernate.engine.transaction.jta.platform.internal.AbstractJtaPlatform;
import org.hibernate.engine.transaction.jta.platform.internal.JtaSynchronizationStrategy;
import org.hibernate.engine.transaction.jta.platform.internal.SynchronizationRegistryAccess;
import org.hibernate.engine.transaction.jta.platform.internal.SynchronizationRegistryBasedSynchronizationStrategy;
import com.arjuna.ats.arjuna.common.ObjectStoreEnvironmentBean;
import com.arjuna.ats.internal.arjuna.objectstore.VolatileStore;
import com.arjuna.common.internal.util.propertyservice.BeanPopulator;
/**
* A test-specific implementation of the JtaPlatform contract for testing JTA-based functionality.
*
* @author Steve Ebersole
*/
public class JtaPlatformStandardTestingImpl extends AbstractJtaPlatform {
public static final JtaPlatformStandardTestingImpl INSTANCE = new JtaPlatformStandardTestingImpl();
private final TransactionManager transactionManager;
private final UserTransaction userTransaction;
private final TransactionSynchronizationRegistry synchronizationRegistry;
private final JtaSynchronizationStrategy synchronizationStrategy;
public JtaPlatformStandardTestingImpl() {
BeanPopulator
.getDefaultInstance( ObjectStoreEnvironmentBean.class )
.setObjectStoreType( VolatileStore.class.getName() );
BeanPopulator
.getNamedInstance( ObjectStoreEnvironmentBean.class, "communicationStore" )
.setObjectStoreType( VolatileStore.class.getName() );
BeanPopulator
.getNamedInstance( ObjectStoreEnvironmentBean.class, "stateStore" )
.setObjectStoreType( VolatileStore.class.getName() );
transactionManager = com.arjuna.ats.jta.TransactionManager.transactionManager();
userTransaction = com.arjuna.ats.jta.UserTransaction.userTransaction();
synchronizationRegistry =
new com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionSynchronizationRegistryImple();
synchronizationStrategy = new SynchronizationRegistryBasedSynchronizationStrategy(
new SynchronizationRegistryAccess() {
@Override
public TransactionSynchronizationRegistry getSynchronizationRegistry() {
return synchronizationRegistry;
}
}
);
}
public void reset() throws SystemException {
if ( transactionManager != null ) {
if ( transactionManager.getStatus() != Status.STATUS_NO_TRANSACTION ) {
transactionManager.rollback();
}
}
if ( userTransaction != null ) {
if ( userTransaction.getStatus() != Status.STATUS_NO_TRANSACTION ) {
userTransaction.rollback();
}
}
}
public TransactionManager transactionManager() {
return retrieveTransactionManager();
}
public UserTransaction userTransaction() {
return retrieveUserTransaction();
}
public TransactionSynchronizationRegistry synchronizationRegistry() {
return synchronizationRegistry;
}
@Override
protected TransactionManager locateTransactionManager() {
return transactionManager;
}
@Override
protected boolean canCacheTransactionManager() {
return true;
}
@Override
protected UserTransaction locateUserTransaction() {
return userTransaction;
}
@Override
protected boolean canCacheUserTransaction() {
return true;
}
@Override
protected JtaSynchronizationStrategy getSynchronizationStrategy() {
return synchronizationStrategy;
}
}

View File

@ -0,0 +1,117 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2015, 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.test.resource.transaction.jta;
import org.hibernate.resource.jdbc.spi.JdbcSessionOwner;
import org.hibernate.resource.transaction.spi.TransactionCoordinatorOwner;
import org.jboss.logging.Logger;
/**
* @author Steve Ebersole
*/
public class TransactionCoordinatorOwnerTestingImpl implements TransactionCoordinatorOwner {
private static final Logger log = Logger.getLogger( TransactionCoordinatorOwnerTestingImpl.class );
private boolean active;
private int beginCount;
private int beforeCompletionCount;
private int successfulCompletionCount;
private int failedCompletionCount;
public TransactionCoordinatorOwnerTestingImpl() {
this( true );
}
public TransactionCoordinatorOwnerTestingImpl(boolean active) {
this.active = active;
}
public int getBeforeCompletionCount() {
return beforeCompletionCount;
}
public int getSuccessfulCompletionCount() {
return successfulCompletionCount;
}
public int getFailedCompletionCount() {
return failedCompletionCount;
}
public void reset() {
beginCount = 0;
beforeCompletionCount = 0;
successfulCompletionCount = 0;
failedCompletionCount = 0;
}
public void deactivate() {
active = false;
}
@Override
public boolean isActive() {
return active;
}
@Override
public void afterTransactionBegin() {
log.debug( "#afterTransactionBegin called" );
beginCount++;
}
@Override
public void beforeTransactionCompletion() {
log.debug( "#beforeTransactionCompletion called" );
beforeCompletionCount++;
}
@Override
public void afterTransactionCompletion(boolean successful) {
log.debug( "#afterTransactionCompletion called" );
if ( successful ) {
successfulCompletionCount++;
}
else {
failedCompletionCount++;
}
}
@Override
public JdbcSessionOwner getJdbcSessionOwner() {
return null;
}
@Override
public void setTransactionTimeOut(int seconds) {
}
@Override
public void flushBeforeTransactionCompletion() {
}
}