-
Notifications
You must be signed in to change notification settings - Fork 192
DynamicProxyable for ReactiveCouchbaseRepository using ThreadLocal #1838
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
Comments
The two calls are independent of each other - it doesn't matter that they are in different threads. The DynamicProxyable.invoke() intercept the save() call, stores the scope in a ThreadLocal) and then in calls the actual repository.save() method which retrieves the ThreadLocal - it's all in the same Thread. I'll check if there could be an issue with one execution clearing out the ThreadLocal before another execution reads it. It would be helpful if you provide your complete example so I can be sure I'm running the same thing that you are. |
Okay! Please refer to example in |
Thanks. The issue was introduced with transactions support and is in the repository.save() method. No other repository methods will have the issue. save() starts the flux publisher before the ThreadLocal information is retrieved to determine if it is a transaction or not in order to choose one of insert, upsert or replace. So when the ThreadLocal information is retrieved in ReactiveInsertByIdOperationSupport.one() - it's in a different thread. The work-around is to use reactiveTemplate.withScope(scopeName).withCollection(collectinName).insertById(User.class).one(user). Or upsert() or replace() as required. Note that the collection name is also needed - since it's not using the repository, the repository annotation will not be used. |
The issue was introduced when the Mono.deferContextual() was added to determine if the save() is in a transaction. It may be executing in a different thread when the PseudoArgs (scope, collection, and options) are retrieved ThreadLocal. This change ensures scope and collection are retrieved, but options are ignored and discarded. Closes #1838.
The issue was introduced when the Mono.deferContextual() was added to determine if the save() is in a transaction. It may be executing in a different thread when the PseudoArgs (scope, collection, and options) are retrieved ThreadLocal. This change ensures scope and collection are retrieved, but options are ignored and discarded. Closes #1838.
The issue was introduced when the Mono.deferContextual() was added to determine if the save() is in a transaction. It may be executing in a different thread when the PseudoArgs (scope, collection, and options) are retrieved ThreadLocal. This change ensures scope and collection are retrieved, but options are ignored and discarded. Closes #1838.
The issue was introduced when the Mono.deferContextual() was added to determine if the save() is in a transaction. It may be executing in a different thread when the PseudoArgs (scope, collection, and options) are retrieved ThreadLocal. This change ensures scope and collection are retrieved, but options are ignored and discarded. Closes #1838.
The issue was introduced when the Mono.deferContextual() was added to determine if the save() is in a transaction. It may be executing in a different thread when the PseudoArgs (scope, collection, and options) are retrieved ThreadLocal. This change ensures scope and collection are retrieved, but options are ignored and discarded. Closes #1838.
The issue was introduced when the Mono.deferContextual() was added to determine if the save() is in a transaction. It may be executing in a different thread when the PseudoArgs (scope, collection, and options) are retrieved ThreadLocal. This change ensures scope and collection are retrieved, but options are ignored and discarded. Closes #1838.
Thanks! |
Spring Boot Version: 3.1.4
Spring Dependency Management Version: 1.1.3
Couchbase Enterprise: 7.2.2
Project Link: couchbasedynamicproxyable-demo.zip
As mentioned in DynamicProxyable it is mentioned that, it uses ThreadLocal, is it correct in reactive paradigm ?
That's why when I am trying this in reactive programming it is not consistent rather I could say, not supporting.
I have created a demo project recreating this issue.
This piece of code has two separate repository call to the same repository mentioning withScope().
In this example if both the repository calls happen in the same thread, then there is no issue but if the threads are different, the call fails as it fails to pick the correct scope from the ThreadLocal because it is different thread.
This is the log:
As can be seen in second line of the log, the scope set is
_default
, which is incorrect as it should betenant
.Instead of plain then() operator, if I try deferring it works,
.then(Mono.defer(() -> userRepository.withScope(TENANT_SCOPE).save(user).log("2")))
Any appropriate solution ? This is important for multi tenant implementation.
The text was updated successfully, but these errors were encountered: