All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.persistence.transaction.JTATransactionController Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * Copyright (c) 1998, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
//     10/24/2017-3.0 Tomas Kraus
//       - 526419: Modify EclipseLink to reflect changes in JTA 1.1.
package org.eclipse.persistence.transaction;

import javax.transaction.*;

import org.eclipse.persistence.exceptions.TransactionException;

/**
 * 

* Purpose: TransactionController implementation for JTA 1.0 *

* Description: Implements the required behavior for controlling JTA 1.0 * transactions. Specific JTA implementations may need to extend this class * when special controller behavior is necessary. *

* The JTA TransactionManager must be obtained and set on the * instance in order for a Synchronization listener to be registered against * the transaction. This can be done either by extending this class and defining * acquireTransactionManager() to return the manager for the server, or by using * this class and explicitly calling the setTransactionManager() method on it * after the fact. * e.g. * TransactionManager mgr = controller.jndiLookup("java:comp/TransactionManager"); * controller.setTransactionManager(mgr); *

* If a different listener needs to be used for synchronization, the * SynchronizationListenerFactory should be set on the controller instance. * The listener subclass should implement the factory interface, so that * setting the factory is simply a matter of assigning an instance of the * listener. * e.g. * controller.setSynchronizationListenerFactory( * new DifferentServerSynchronizationListener()); * * The default listener factory creates instances of JTATransactionListener. * * @see JTASynchronizationListener * @see AbstractTransactionController */ public class JTATransactionController extends AbstractTransactionController { // Allows transaction manager to be set statically. protected static TransactionManager defaultTransactionManager; // Primary point of integration with JTA protected TransactionManager transactionManager; /** * PUBLIC: * Return a new controller for use with a JTA 1.0 compliant TransactionManager. */ public JTATransactionController() { super(); this.listenerFactory = new JTASynchronizationListener(); try { this.transactionManager = acquireTransactionManager(); } catch (Exception ex) { throw TransactionException.errorObtainingTransactionManager(ex); } } /** * PUBLIC: * Return a new controller for use with a JTA 1.0 compliant TransactionManager. */ public JTATransactionController(TransactionManager transactionManager) { super(); this.listenerFactory = new JTASynchronizationListener(); this.transactionManager = transactionManager; } /** * INTERNAL: * Register the specified synchronization listener with the given active * transaction. * * @param listener The synchronization listener created for this transaction * @param txn The active transaction for which notification is being requested */ protected void registerSynchronization_impl(AbstractSynchronizationListener listener, Object txn) throws Exception { ((Transaction)txn).registerSynchronization((Synchronization)listener); } /** * INTERNAL: * Return the active external transaction, or null if none is currently * active for this thread. * * @return The active transaction object or id, or null if no transaction is active */ protected Object getTransaction_impl() throws Exception { return getTransactionManager().getTransaction(); } /** * INTERNAL: * Return a key for the specified external transaction object. * The key is just something that can be inserted into a hashtable (must support * hashCode() and equals() methods). * * @param transaction The transaction to which the returned key applies (may be null) * @return A key for the passed in transaction, or null if no transaction specified */ protected Object getTransactionKey_impl(Object transaction) throws Exception { // Use the transaction itself as the key return transaction; } /** * INTERNAL: * Return the transaction status as an object. We will pass around Integers that * wrap the int JTA status values. * * @return The current transaction status */ protected Object getTransactionStatus_impl() throws Exception { return Integer.valueOf(getTransactionManager().getStatus()); } /** * INTERNAL: * Begin an external transaction. */ protected void beginTransaction_impl() throws Exception { getTransactionManager().begin(); } /** * INTERNAL: * Commit the external transaction. */ protected void commitTransaction_impl() throws Exception { getTransactionManager().commit(); } /** * INTERNAL: * Roll back the external transaction. */ protected void rollbackTransaction_impl() throws Exception { getTransactionManager().rollback(); } /** * INTERNAL: * Mark the external transaction for rollback. */ protected void markTransactionForRollback_impl() throws Exception { getTransactionManager().setRollbackOnly(); } /** * INTERNAL: * Return true if the status indicates that a transaction can be started. This * would normally mean that no transaction is currently active. * * @param status The current transaction status * @return true if the current state allows for a transaction to be started */ protected boolean canBeginTransaction_impl(Object status) { return getIntStatus(status) == Status.STATUS_NO_TRANSACTION; } /** * INTERNAL: * Return true if the status indicates that a transaction can be committed. This * would normally mean that a transaction is currently active. * * @param status The current transaction status * @return true if the current state allows for a transaction to be committed */ protected boolean canCommitTransaction_impl(Object status) { return getIntStatus(status) == Status.STATUS_ACTIVE; } /** * INTERNAL: * Return true if the status indicates that a transaction can be rolled back. This * would normally mean that a transaction is currently active. * * @param status The current transaction status * @return true if the current state allows for a transaction to be rolled back */ protected boolean canRollbackTransaction_impl(Object status) { return getIntStatus(status) == Status.STATUS_ACTIVE; } /** * INTERNAL: * Return true if the status indicates that the SQL should be issued to the db. * This would normally mean that a transaction was active. * * @param status The current transaction status * @return true if the current state allows for the SQL to be sent to the database */ protected boolean canIssueSQLToDatabase_impl(Object status) { int stat = getIntStatus(status); return ((stat == Status.STATUS_ACTIVE) || (stat == Status.STATUS_PREPARING)); } /** * INTERNAL: * Return true if the status indicates that the unit of work should be merged * into the shared cache. This would normally mean that the transaction was * committed successfully. * * @param status The current transaction status * @return true if the current state dictates that the unit of work should be merged */ protected boolean canMergeUnitOfWork_impl(Object status) { return getIntStatus(status) == Status.STATUS_COMMITTED; } /** * INTERNAL: * Return true if the transaction is rolled back. */ public boolean isRolledBack_impl(Object status) { return getIntStatus(status) == Status.STATUS_ROLLEDBACK; } /** * INTERNAL: * Obtain and return the JTA TransactionManager on this platform. * By default try java:comp JNDI lookup. * * This method can be can be overridden by subclasses to obtain the * transaction manager by whatever means is appropriate to the server. * This method is invoked by the constructor to initialize the transaction * manager at instance-creation time. Alternatively the transaction manager * can be set directly on the controller instance using the * setTransactionManager() method after the instance has been created. * * @return The TransactionManager for the transaction system */ protected TransactionManager acquireTransactionManager() throws Exception { if (defaultTransactionManager != null) { return defaultTransactionManager; } return null; } /** * INTERNAL: * Convenience method to return the int value of the transaction status. * Assumes that the status object is an Integer. */ protected int getIntStatus(Object status) { return ((Integer)status).intValue(); } /** * PUBLIC: * Return the transaction manager used to control the JTA transactions. * * @return The JTA TransactionManager that is used to obtain transaction * state information and control the active transaction. */ public TransactionManager getTransactionManager() { return transactionManager; } /** * PUBLIC: * Set the transaction manager used to control the JTA transactions. * * @param mgr A valid JTA TransactionManager that can be * accessed by this controller to obtain transaction state information and * control the active transaction. */ public void setTransactionManager(TransactionManager mgr) { transactionManager = mgr; } /** * INTERNAL: * Convert the status to a string for tracing. */ static String[] codes = { "STATUS_ACTIVE", "MARKED_ROLLBACK", "PREPARED", "COMMITTED", "ROLLEDBACK", "UNKNOWN", "NO_TRANSACTION", "PREPARING", "COMMITTING", "ROLLING_BACK" }; protected String statusToString_impl(Object status) { int statusCode = getIntStatus(status); return codes[statusCode]; } public static TransactionManager getDefaultTransactionManager() { return defaultTransactionManager; } /** * PUBLIC: * Set the JTA transaction manager to be used. * This can be called directly before login to configure JTA integration manually, or using Spring injection. */ public static void setDefaultTransactionManager(TransactionManager defaultTransactionManager) { JTATransactionController.defaultTransactionManager = defaultTransactionManager; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy