I'm migrating my EJBs to Spring beans and i have an issue with concurrency
on some beans i have annotation @Lock(LockType.READ)
or @Lock(LockType.WRITE)
on methods and class when concurrency was managed by container, but in Spring concurrency is managed by bean, what equivalent i could do in Spring regarding for locking two simultaneous read/write actions ?
For example on this class :
@Singleton
@Lock(READ)
public class SharedSingletonBean {
private String data;
private String status;
public String getData() {
return data;
}
public String getStatus() {
return status;
}
@Lock(WRITE)
public void setStatus(String newStatus) {
status = newStatus;
}
}
For @Lock(READ)
, you have nothing to do as the READ
value means that the method does only reading and that it can be concurrently accessed, or shared, with several clients.
It is the case for example for these two methods :
public String getData() {
return data;
}
public String getStatus() {
return status;
}
For @Lock(WRITE)
as this one :
@Lock(WRITE)
public void setStatus(String newStatus) {
status = newStatus;
}
it means that the method does writing.
So actually, the WRITE
value makes the container to prevent any client to invoke the method if another client executing it.
To do the same thing with Spring, using the volatile
modifier for the String
field could be enough as you do only an assignment in the method.
You would not have concurrency or no updated value issue as an assignment for a volatile
variable is always atomic and updated for other threads and with this solution, as in your actual case, the last one client is always right.
Also, as a side note, I am not very convinced of the correct use of @Lock READ
and WRITE
here.
If you have more statements and that this could not be invoked atomically and in a transparent way for other clients, you could use a synchronized
statement on the current object :
public void setStatus(String newStatus) {
synchronize(this){
myStatement();
myOtherStatement();
status = newStatus;
}
}