David J. M. Karlsen opened SPR-13724 and commented

Looking at

http://docs.spring.io/autorepo/docs/spring/3.2.5.RELEASE/javadoc-api/org/springframework/transaction/support/TransactionSynchronization.html

and https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/transaction/event/TransactionalEventListener.html / https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/transaction/event/TransactionPhase.html

it would be nice to have a new phase BEFORE_CREATE - emitted by the framework just before it calls the underlying resource to create a new transaction.

The reason for this is that we need to initialize https://www-01.ibm.com/support/knowledgecenter/SSTVLU_8.6.0/com.ibm.websphere.extremescale.javadoc.doc/topics/com/ibm/websphere/objectgrid/spring/SpringLocalTxManager.html with an ObjectGrid instance (kept threadlocal inside that implementation) just before it will be called by spring to get one.

We do this today by composing a custom annotation (annotated again with @Transactional) and intercepting execution with an aspect - but it would be nice to put it directly into framework classes - and I guess it could be interesting for other usecases as well.


Issue Links: - #16214 TransactionSynchronizationManager - throw an Exception or log a warning if a Synchronization wants to add a Synchronization and afterCompletion is already called

1 votes, 3 watchers

Comment From: spring-projects-issues

Lukas Eder commented

I confirm that this would be a nice addition to the existing transaction lifecycle listener SPI. In TransactionPhase, we have commit/rollback related hooks, but not "begin" related ones.

In addition to the interesting use-case mentioned in this ticket, I have another one from a previous customer where they look up Java EE UserTransactions via JNDI and after doing so, they implemented some logic initialising the Oracle Connection's PL/SQL context with global variables for the session (user ID, contract number, accounts, etc.). This context was part of the application design and was used throughout their stored procedures and views as an additional security layer directly in the database. The ideal place to do this is when a transaction starts. Because they didn't use DI, it was easy for them to implement this "manually" because they created the transaction themselves.

With DI (e.g. Spring Transactional), users rely on the DI SPIs made available by Spring, and this particular mechanism is currently missing:

  • Register a hook to execute prior to transaction creation (as suggested)
  • Register a hook to execute just after transaction creation

For further reference, there had been a support request just recently on the jOOQ mailing list that was asking about this very feature, with another use-case: Auditing https://groups.google.com/forum/#!msg/jooq-user/1JwWMChD2SM/uGT_4fZqAgAJ

Comment From: jhoeller

The reason why TransactionSynchronization and TransactionalEventListener do not have any begin-level hooks is that such synchronizations are meant to be registered on the fly while accessing some additional resources or publishing some event. No TransactionSynchronization is registered at transaction begin yet, it is just not part of that model. That also applies to TransactionalEventListener which is effectively about deferred processing of custom application events depending on the transaction state, not about general callbacks to initialize transactional resources in specific transaction phases. In other words, this is not a transactional lifecycle SPI, it is a deferred callback model for aligning with the outcome of a current transaction.

For initialization purposes, we'd have to introduce specific callbacks that the transaction manager invokes on begin and on completion, or as suggested above, decorate transactional processing with an aspect. This could also be implemented in a PlatformTransactionManager decorator or in a custom subclass of a concrete PlatformTransactionManager implementation, performing certain initialization before or after beginning the transaction and before or after completion of the transaction.

In any case, this is not part of the scope of transaction synchronizations, so I'll close this issue from that perspective.