-
Notifications
You must be signed in to change notification settings - Fork 434
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
Transactional methods close before transaction is commited #187
Comments
Have you enabled proxy as described in https://github.com/LogNet/grpc-spring-boot-starter/pull/58/files? |
This enabled by default in the version of Spring boot that I am using. I can verify in stack trace that the method call is proxied. I can also use lazy loaded entries in received entities. |
Basically this represents a race condition between the database query in the unit test and the transaction handling of the proxy. I suspect the root cause for my inconsistent test result is the following order of execution.
|
OK, so the problem is that transactional annotation works around the method execution and the transaction is committed after the method completes and client's callback is invoked while the method is still being executed, triggered by |
I think this issue is not limited to unit tests. It could also be a problem in production scenarios. Imagine the client adds an entity to the database and then requests a list of all entities including the newly created one. The probability for being an issue is pretty low considering network latency. But unfortunately nothing is perfect and the database could need more time to successfully commit the transaction. But you have a good point that deferring execution of onCompleted is probably not a good idea. In order to handle transactional methods it there needs to be a mechanism to separate the processing part from returning the result/error. |
OK, in this case I would suggest to extract the transactional business logic into separate service bean method, mark it as transactional, autowire it into grpc service and call its method from grpc. |
This is the same approach I suggested in #41 from the beginning |
Is it possible to archive this with some spring or grpc magic? I imagine it should be possible to proxy calls of onCompleted and onError. |
IMHO, externalizing the transactional logic into separate service is the fastest and most reliable approach. |
This is exactly what I did. It's best to leave this as implementation detail in the business logic. It would be hard to handle streaming API in a generic way. |
This only works if you have the result in memory, it doesn't if you stream from the database. See grpc/grpc-java#4694 (comment) |
@micheljung , good catch, I suppose we should ask spring team to support |
I have already found some discussion around @transactional in #41. Now I stumbled across an issue in my integration tests where the transaction is not committed yet but the gRPC call already returned. I'd like to help to contribute to this issue but I am missing some understanding of both the gRPC lifecycle of calls and the mechanism of dynamic proxies in Spring. Below an example of such a unit/integration test.
My potential solution to this issue is to simple delay the calls to onNext, onError and onCompleted after the transaction is committed. This solution would only work for non streaming rpc calls. Any thoughts about this one?
The text was updated successfully, but these errors were encountered: