jakartaee / transactions

Welcome to the Jakarta EE Transactions API Project (formerly JTA)
https://jakartaee.github.io/transactions/
Other
28 stars 29 forks source link

Standardise way to obtain the TransactionManager #209

Open arjantijms opened 2 years ago

arjantijms commented 2 years ago

Jakarta Transactions specifies the type TransactionManager, but no portable way to obtain this.

As a result, as of today we still need custom integration code like the one shown below (from EclipseLink) for every known server:

public class GlassfishTransactionController11 extends JTA11TransactionController {

    public GlassfishTransactionController11() {
        super();
    }

    /**
     * INTERNAL:
     * Obtain and return the JTA TransactionManager on this platform
     */
    @Override
    protected TransactionManager acquireTransactionManager() throws Exception {
        return (TransactionManager)jndiLookup(GlassfishTransactionController.JNDI_TRANSACTION_MANAGER_NAME);
    }

    /**
     * INTERNAL:
     * Obtain and return the JTA 1.1 {@link TransactionSynchronizationRegistry} on this platform.
     *
     * @return the {@code TransactionSynchronizationRegistry} for the transaction system
     * @since 2.7.1
     */
    @Override
    protected TransactionSynchronizationRegistry acquireTransactionSynchronizationRegistry() throws TransactionException {
        return (TransactionSynchronizationRegistry)jndiLookup(JNDI_TRANSACTION_SYNCHRONIZATION_REGISTRY);
    }

}

I would like to propose standardising this, using either (or both) a standard JNDI name and/or an build-in CDI bean.

tomjenkinson commented 2 years ago

I am wondering about use cases where having differently configured transaction manager / TSRs might be beneficial?

arjantijms commented 2 years ago

I am wondering about use cases where having differently configured transaction manager / TSRs might be beneficial?

It's needed for exactly the use case that EclipseLink has. It needs access to the transaction manager, and simultaneously it needs to work on Tomcat (where the user can add whatever transaction manager), on GlassFish, on Open Liberty, etc etc.

If a new environment and/or transaction manager comes to the market, EclipseLink must either know about this (and keep it's support updated), or provided specific integration code for EclipseLink. However, if that environment also wants to support Hibernate (not uncommon, especially in modular environment), Hibernate must also be explicitly supported.

All of this explicit support is exactly what standards are supposed to solve.

tomjenkinson commented 2 years ago

Sorry, I was unclear. How would you propose to deal with the situation where the same JVM might want to access two differently configured transaction manager processes (from the same vendor)? Having two transaction manager instances with different JNDI names could, at least theoretically, currently be used to achieve that.

arjantijms commented 2 years ago

I see. Isn't that the same case, more or less, as wanting to have two different UserTransaction instances? Is that really a thing?

If it is, I'd guess providers (or integrators) could introduce an option to not use the default name. Although it seems a theoretical issue indeed, since there's a couple of names already in use which seem to be shared between different providers.

arjantijms commented 2 years ago

Btw, using CDI one could inject Instance<TransactionManager> and then iterate over the different instances.

arjantijms commented 2 years ago

ps. I overlooked that the registry already has a standardised name:

 * <P>In standard application server environments, an instance
 * implementing this interface can be looked up by a standard name via JNDI.
 * The standard name is java:comp/TransactionSynchronizationRegistry.
 *
 * @version Jakarta Transactions 2.0
 * @since JTA 1.1
 */
public interface TransactionSynchronizationRegistry {

So really only TransactionManager is needed.

tomjenkinson commented 2 years ago

I think the TransactionManager is intended for access by the application server (rather than user components) so not having it readily accessible to users via JNDI/injection could be considered an advantage.

I had a quick look at EclipseLink (I might have missed some things and not understood what I found). What I wonder is whether EclipseLink could change it's use of TransactionManager to UserTransaction/TransactionSynchronizationRegistry? I found handing of transactions that seemed it might be replaceable with UserTransaction operations, but I also found:

arjantijms commented 2 years ago

I think the TransactionManager is intended for access by the application server (rather than user components)

More or less, but application servers can be made pluggable as well. JoNAS for instance had that, and Piranha Cloud focusses on that too. Essentially we let the user plug-in a transaction manager (like JoTM, Narayana, Transact, etc).

OndroMih commented 5 months ago

I think the TransactionManager is intended for access by the application server (rather than user components)

This is true. But application server components (like EclipseLink or Hibernate) may be designed to work with multiple application servers. Users may want to plug them into an app server as an alternative to the default provider (e.g. in a Jakarta EE server), or when it's missing (e.g. in Tomcat). It's OK that Transactions spec primarily targets Jakarta EE app servers but it could as well support standalone usage, there's not reason why not.

Since TransactionSynchronizationRegistry already defines a standard JNDI name for the default implementation, TransactionManager could also do it to make it behave the same way.

On top of that, we could also create an SPI to provide custom implementations, e.g. with the Java service loader. The SPI could be a simple interface that has methods to retrieve TransactionSynchronizationRegistry, TransactionManager, and maybe some other implementations. It could then be used also without JNDI. App servers could easily implement the SPI and EclipseLink, Hibernate or other components that depend on JTA would just find the proper implementations in a standard way.

tomjenkinson commented 5 months ago

It would be good to hear from other vendors if they would disagree with binding the TransactionManager with a known name. We could try to get consensus by initiating a thread via the jta-dev mailing list: https://accounts.eclipse.org/mailing-list/jta-dev