If we register another synchronization within registerSynchronization.afterCommit(), the new sync do not take effect.

Another issue is that the result of TransactionSynchronizationManager.isActualTransactionActive() is still True, however, the trx should be completed during afterCommit()

    TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCommit() {
                Log.info("sync alive {}, trx alive {}", TransactionSynchronizationManager.isSynchronizationActive(),
                        TransactionSynchronizationManager.isActualTransactionActive());

                // XXX: could we check this, and not allow it?
                TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
                    @Override
                    public void afterCommit() {
                        System.out.println("Should never reach here");  // XXX: Not work
                    }
                });
            }
    });

This is because it use a snapshot list of all registered syncs, not including the newly added one during executing triggerAfterCommit() within AbstractPlatformTransactionManager.processCommit(). The below show the related source code in spring framework.

        private void triggerAfterCommit(DefaultTransactionStatus status) {
        if (status.isNewSynchronization()) {
            if (status.isDebug()) {
                logger.trace("Triggering afterCommit synchronization");
            }
            TransactionSynchronizationUtils.triggerAfterCommit();    // <--- 1
        }
    }

       public static void triggerAfterCommit() {
        invokeAfterCommit(TransactionSynchronizationManager.getSynchronizations());  // <---- 2
    }

       /**
     * Return an unmodifiable snapshot list of all registered synchronizations
     * for the current thread.
     * @return unmodifiable List of TransactionSynchronization instances
     * @throws IllegalStateException if synchronization is not active
     * @see TransactionSynchronization
     */
    public static List<TransactionSynchronization> getSynchronizations() throws IllegalStateException {
        Set<TransactionSynchronization> synchs = synchronizations.get();
        if (synchs == null) {
            throw new IllegalStateException("Transaction synchronization is not active");
        }
        // Return unmodifiable snapshot, to avoid ConcurrentModificationExceptions
        // while iterating and invoking synchronization callbacks that in turn
        // might register further synchronizations.
        if (synchs.isEmpty()) {
            return Collections.emptyList();
        }
        else {
            // Sort lazily here, not in registerSynchronization.
            List<TransactionSynchronization> sortedSynchs = new ArrayList<>(synchs);
            AnnotationAwareOrderComparator.sort(sortedSynchs);
            return Collections.unmodifiableList(sortedSynchs);      // <------ 3
        }
    }

We expect that we could raise an exception for the second register inside afterCommit() or similar methods

Comment From: DlisKeepOnGoing

I encounter the same problems, but how to solve the problem when we have the situation.

Comment From: snicoll

You haven't shared much about the use case, but TransactionSynchronizationManager and friends are not supposed to be used by application code (see Javadoc). To better understand the problem and hopefully help you, we need a small sample that we can run ourselves to reproduce the problem. Please make it as minimal as possible and without the need of external services.

The project can be shared by attaching a zip to this issue or by pushing the code to a GitHub repository. Thanks.

Comment From: spring-projects-issues

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

Comment From: spring-projects-issues

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.