[go: up one dir, main page]

Skip to content
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

PartTree Delete queries cause nested Spanner transaction when using @Transactional #619

Open
guycall opened this issue Sep 16, 2021 · 5 comments
Labels

Comments

@guycall
Copy link
guycall commented Sep 16, 2021

Describe the bug
I am not sure if this is expected behaviour, but Spanner delete operations raise exception within methods annotated with @Transactional.

Sample

@Transactional
public void handle(String ownerId, List<ItemEntity> newEntities) {

    itemRepository.deleteByOwnerId(ownerId);

    itemRepository.saveAll(newEntities); 
}

On entering this method a transaction is created: Creating new transaction with name [com.xxx.xxx.UpdateItem.handle]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT

But executing deleteByOwnerId then triggers an exception:java.lang.IllegalStateException: There is already declarative transaction open.

I know Spanner does not allow nested transactions, and the docs state "The delete operation happens in a single transaction". But I wonder if this expected behaviour when using @transactional? Should the delete run inside the existing transaction?

Workaround
The workaround is to first read the entities to delete and then call itemRepository.deleteAll(entitiesToDelete)

NB: This is using version 1.2 of spring-cloud-gcp

@guycall guycall changed the title Delete queries causes nested Spanner transaction when using @Transactional Delete queries cause nested Spanner transaction when using @Transactional Sep 16, 2021
@elefeint
Copy link
Contributor

@guycall Thank you for describing the issue in detail. This should, in principle, work, and all repository methods should reuse the declared transaction.

@ddixit14 Can you try to reproduce this scenario (declarative @Transactional annotation on a service method calling a repository delete operation) in one of our samples? Declarative transaction management should work.

@toyopilgrim
Copy link
toyopilgrim commented Sep 17, 2021

As @guycall stated,

itemRepository.deleteByOwnerId(ownerId);

This line is currently not able to work with @Transactional since deleteByOwnerId of spanner repository method will try to do ReadWriteTransaction with a context which has already begun at bean of SpannerTransactionManager(=@transactional). So nested transaction error is occurring then.

Meanwhile, delete/deleteAll just adds the mutation to a buffer not interrupting an existing context with @transactional.

So, straight workaround would be just to replace itemRepository.deleteByOwnerId(ownerId) with deleteAll/delete.

But both scenarios have to work, I believe.

@elefeint
Copy link
Contributor

Thank you for the clarification!

@elefeint elefeint changed the title Delete queries cause nested Spanner transaction when using @Transactional PartTree Delete queries cause nested Spanner transaction when using @Transactional Sep 21, 2021
@elefeint elefeint added the type: bug Something isn't working label Aug 5, 2022
@blakeli0
Copy link
Contributor

Reproduced with the spring-cloud-gcp 4.2.0

Caused by: java.lang.IllegalStateException: There is already declarative transaction open. Spanner does not support nested transactions
	at com.google.cloud.spring.data.spanner.core.SpannerTemplate.lambda$performReadWriteTransaction$20(SpannerTemplate.java:440) ~[classes/:na]
	at com.google.cloud.spring.data.spanner.core.SpannerTemplate.doWithOrWithoutTransactionContext(SpannerTemplate.java:719) ~[classes/:na]
	at com.google.cloud.spring.data.spanner.core.SpannerTemplate.performReadWriteTransaction(SpannerTemplate.java:438) ~[classes/:na]
	at com.google.cloud.spring.data.spanner.repository.query.PartTreeSpannerQuery.executeRawResult(PartTreeSpannerQuery.java:71) ~[classes/:na]
	at com.google.cloud.spring.data.spanner.repository.query.AbstractSpannerQuery.execute(AbstractSpannerQuery.java:63) ~[classes/:na]
	at com.google.cloud.spring.data.spanner.repository.query.PartTreeSpannerQuery.execute(PartTreeSpannerQuery.java:35) ~[classes/:na]

@zhumin8
Copy link
Contributor
zhumin8 commented Apr 23, 2024

fyi, the above 2 mentions are not related to this issue, and due to url mismatch in migrating the r2dbc module.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants