cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

Failed to open a new transaction when using multi thread to read repository

0 Likes
1,449

I am referring to URL:

https://cap.cloud.sap/docs/java/consumption-api

Please get back to me on the following feedback:

How can I use multi thread to get two different repo with differnt data in parallel?

It will throw an error: Failed to open a new transaction

But if we are not using multi thread, just go through one by one. And it is ok.


So how can we using multi thread to read data?

When I have two method in the repository as below:

ReadTestRepo.class:

public Result getTest1() {

return persistenceService.run(Select.from(Test1_.CDS_NAME).limit(top));<br>

}

public Result getTest2() {

return persistenceService.run(Select.from(Test2_.CDS_NAME).limit(top));<br>

}

And in my main java as below:

main(){

ExecutorService executorService = Executors.newFixedThreadPool(2);
ExecutionInsightCallable resoureCallableResource = new ExecutionInsightCallable("test1",ReadTestRepo);
ExecutionInsightCallable resoureCallableDocument = new ExecutionInsightCallable("test2",ReadTestRepo);
List<ExecutionInsightCallable> callableList = new ArrayList<>();<br>callableList.add(resoureCallableResource);<br>callableList.add(resoureCallableDocument);
@override public Result call(){ if(name.equals("test1")){ return ReadTestRepo.test1() }else{ return ReadTestRepo.test2()
} }
List<Future<Result>> results = executorService.invokeAll(callableList);

}

Accepted Solutions (1)

Accepted Solutions (1)

marcbecker
Product and Topic Expert
Product and Topic Expert

When executing database queries in an asynchronous thread you need to make sure to propagate the tenant in the request context from the parent thread. Otherwise CAP doesn't know to which tenant HDI container to connect. This is described in our documentation here: https://cap.cloud.sap/docs/java/request-contexts#threading-requestcontext

RequestContextRunner runner = runtime.requestContext();
Future<Result> result = Executors.newSingleThreadExecutor().submit(() -> {
	return runner.run(threadContext -> {
		return persistenceService.run(Select.from(Books_.class));
	});
});<br>
0 Likes
Thanks a lot! It could also help me as well. I had a different situation but the same problem. I had an asynchrony call to other service and when I got my response my tenant-context was gone and I got "Ensure authenticated user context is provided and contains tenant information". Make sense now. Thank you again for your explanation!

Answers (0)