Skip to content

Possible bug when using transactions and TransactionalEventListener #1776

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
jsaramago opened this issue Jul 5, 2023 · 6 comments
Open
Labels
status: feedback-provided Feedback has been provided

Comments

@jsaramago
Copy link

Hi,

I'm trying to use transactions and TransactionalEventListener, but it seams that spring have some incompatibly issue with this in the version 3.1.1 (I had this working on the version 2.7.13).

When the transaction is committed the TransactionalEventListener isn't been triggered and on the logs I got this entry:

2023-07-05T10:48:35.333+01:00 DEBUG 6435 --- [       cb-txn-6] actionalApplicationListenerMethodAdapter : No transaction is active - skipping org.springframework.context.PayloadApplicationEvent[source=org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@65e61854, started on Wed Jul 05 10:48:32 WEST 2023]

Also if I check my bucket I got some extra documents with binary values:
image

In the file couchbaseTransactions.zip is possible to check my current approach to get this working.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jul 5, 2023
@mikereiche
Copy link
Collaborator

The couchbase transaction does get processed and TransactionalApplicationListenerMethodAdapter.onApplicationEvent() does get triggered with the event having the DataCreated object as the payload. But it falls through to the 'else'.

	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		if (TransactionSynchronizationManager.isSynchronizationActive() &&
				TransactionSynchronizationManager.isActualTransactionActive()) {
			TransactionSynchronizationManager.registerSynchronization(
					new TransactionalApplicationListenerSynchronization<>(event, this, this.callbacks));
		}
		else if (this.annotation.fallbackExecution()) {
			if (this.annotation.phase() == TransactionPhase.AFTER_ROLLBACK && logger.isWarnEnabled()) {
				logger.warn("Processing " + event + " as a fallback execution on AFTER_ROLLBACK phase");
			}
			processEvent(event);
		}
		else {
			// No transactional event execution at all
			if (logger.isDebugEnabled()) {
				logger.debug("No transaction is active - skipping " + event);
			}
		}
	}

@mikereiche mikereiche added status: feedback-provided Feedback has been provided and removed status: waiting-for-triage An issue we've not yet triaged labels Jul 7, 2023
@jsaramago
Copy link
Author

Hi @mikereiche, we saw this same behaviour in our side. I think that the problem is that spring doesn't know that there is an active transaction. With this, spring should be aware that a transaction is running because the event is sent inside a method that is annotated with @Transactional. This line of thought is correct?

@mikereiche
Copy link
Collaborator

mikereiche commented Jul 11, 2023

Yes.
This worked in 2.7.13? With which version of spring-data-couchbase?
I don't think that spring-data-couchbase transactions uses TransactionSynchronizationManager, so this behavior doesn't surprise me. The check for being in a couchbase transaction is

org.springframework.data.couchbase.core.TransactionSupport.checkForTransactionInThreadLocalStorage() [ the method name is a bit of a misnomer].

Couchbase transactions probably needs to be calling TransactoinSynchronizationManager.bindResource() / unbindResource().

@jsaramago
Copy link
Author

This worked with spring boot 2.7.13 and with spring dependency management 1.0.15.RELEASE. I don't know what was the spring-data-couchbase version.

@mguney
Copy link

mguney commented Apr 17, 2025

This issue is still exists. I have "@transactional" block. But It publish a event. But TransacionalEventListener doesnt consume it.

I think. Spring doensnt know active transactions because of "CallbackPreferringPlatformTransactionManager"

Spring Boot 3.4.4, spring-data-couchbae 5.4.4

@mikereiche
Copy link
Collaborator

mikereiche commented Apr 17, 2025

Can you provide the repo with your project? Or a jar?

But TransacionalEventListener doesnt consume it.

There is no listener required for transactions. I don't know what TransactionalEventListener is.

I have "@transactional" block.

The @transactional annotation applies to methods. The method must be in a class other than the one it is called from, otherwise it will be called directly without being intercepted. org.springframework.data.couchbase.core.TransactionSupport.checkForTransactionInThreadLocalStorage() can be used to determine if the call has been intercepted and is being executed in a transaction.

@EnableTransactionManagement also needs to be specified in your implementation of the config class. The base class (AbstractCouchbaseConfiguration) has the other definitions required. The transactionInterceptorCustomizer() sets up the interceptor to use for @transactional code.

Here are the transaction tests we run - there are about 500 of them.
https://github.com/spring-projects/spring-data-couchbase/tree/main/src/test/java/org/springframework/data/couchbase/transactions

To run them against a local cb server, you will need to replace src/test/resources/integration.properties with something like this:

# Couchbase Integration-Test Default Properties
cluster.type=unmanaged
cluster.unmanaged.seed=127.0.0.1:8091
cluster.adminUsername=Administrator
cluster.adminPassword=password
cluster.unmanaged.numReplicas=0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: feedback-provided Feedback has been provided
Projects
None yet
Development

No branches or pull requests

4 participants