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

AbstractJdbcCall's compiled variable should be declared as volatile [SPR-13617] #18195

Closed
spring-issuemaster opened this Issue Oct 28, 2015 · 4 comments

Comments

Projects
None yet
2 participants
@spring-issuemaster
Copy link
Collaborator

spring-issuemaster commented Oct 28, 2015

Shimi Bandiel opened SPR-13617 and commented

AbstractJdbcCall contains a Double-Checked Locking code over the compiled field.
It should be declared volatile to avoid ordering issues that can result in race-condition scenarios.


Affects: 3.2.15, 4.1.8, 4.2.2

Referenced from: commits d42cc14, 81342f1, 0f4e4fc

Backported to: 4.1.9, 3.2.16

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

spring-issuemaster commented Oct 28, 2015

Juergen Hoeller commented

Fair enough, we'll declare it as volatile.

However, please note that the effect is rather minimal: Since compilation is a one-time change in such an instance (i.e. an operation is never going to get un-compiled or re-compiled), other threads may miss an update to the compiled variable when it switches from false to true (which is an atomic operation with fully constructed state to be seen at any point). With checkCompiled(), this means it will unnecessarily invoke compile() - which checks the compiled flag again anyway, but within a synchronized block. So effectively, we optimize access via volatile to consistently avoid full synchronization...

Juergen

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

spring-issuemaster commented Oct 28, 2015

Shimi Bandiel commented

I think that the really dangerous scenario can happen is the CPU will re-order the write to the compiled flag to a place before the 'compilation-logic' happens.
In that case another thread may use an non-compiled version of the object.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

spring-issuemaster commented Oct 28, 2015

Juergen Hoeller commented

Good point; I haven't seen this happening yet but it might theoretically occur.

The common version of the problem is delayed exposure of the new value to other threads since the CPU cache contains the stale old version still... even that is worth addressing since we don't want to enter full synchronization without a hard reason here.

Juergen

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

spring-issuemaster commented Oct 28, 2015

Juergen Hoeller commented

I've addressed the same problem in AbstractJdbcInsert and RdbmsOperation as well.

Juergen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment