Skip to content

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

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

Closed
spring-projects-issues opened this issue Oct 28, 2015 · 4 comments
Assignees
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

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-projects-issues
Copy link
Collaborator Author

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-projects-issues
Copy link
Collaborator Author

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-projects-issues
Copy link
Collaborator Author

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-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

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

Juergen

@spring-projects-issues spring-projects-issues added type: bug A general bug in: data Issues in data modules (jdbc, orm, oxm, tx) status: backported An issue that has been backported to maintenance branches labels Jan 11, 2019
@spring-projects-issues spring-projects-issues added this to the 4.2.3 milestone Jan 11, 2019
This was referenced Jan 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants