Uploaded image for project: 'Agroal'
  1. Agroal
  2. AG-289

AgroalDataSource configuration may cause circular dependencies with transaction manager initialization

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Major Major
    • None
    • 3.0
    • pool, spring
    • None
    • False
    • Hide

      None

      Show
      None
    • False

      I'm using Agroal to set up connection pooling with Narayana.

      I'm using Spring Boot and setting up the necessary configuration by myself, by looking at what dev.snowdrop.boot.narayana.autoconfigure.NarayanaAutoConfiguration andĀ AgroalDataSourceAutoConfiguration are doing it.

      I think there's one thing that should be tweaked.
      The transaction manager needs the data sources to be ready, in order to start. Additionally, it should be shut down before the data sources are. This is particularly true having async recovery threads. Indeed, the NarayanaBeanFactoryPostProcessor is setting up such "depends on" dependencies between the transaction manager and the data sources. It's reasonable, other JTA implementations for Spring Boot are doing the same.

      However, if the data source is an Agroal one, and then the Agroal configuration kicks in, it needs a reference to the transaction manager (either through a Spring JtaTransactionManager or through a TransactionManager/TransactionSynchronizationRegistry pair) to invoke its setJtaTransactionIntegration, which registers the binding. The actual usage of those components is delayed until something really needs to be done, and from my tests it seems it's somehow working anyway, but this dependency between beans is breaking the initialization order and I think this is not ideal. Indeed, during the AgroalDataSource initialization, the transaction manager gets initialized by Spring, even though it still cannot receive connections from the data source.

      To overcome this, I personally wrote a TransactionIntegration implementation that delegates to a lazily NarayanaTransactionIntegration instance, which in turn retrievesĀ the transaction manager and synchronization registry upon first invocation of one of its methods. But anyway, probably it would be better if Agroal's setJtaTransactionIntegration out-of-the-box supported to specify a Supplier<TransactionIntegration>, rather than TransactionIntegration direct reference. Of course its get() method should then only be called upon actual usage.

      As a side note (not related to this): I would suggest to add some documentation for connectable and firstResource flags required by the NarayanaTransactionIntegration constructors: I couldn't find it anywhere, I think I guessed the purpose of the former by checking some WildFly documentation.

              lbarreiro-1 Luis Barreiro
              mauromol Mauro Molinari
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated: