Runtime tools : Service components : Remote cache service : How to use the remote cache : Access data by using locks
  
Access data by using locks
For data that is regularly updated, you must put a lock on the data in the cache before using the data in an operation. The lock prevents race conditions (two or more operations attempting to update the same data at the same time). Other operations are then prevented from changing the data in the cache until the first operation is complete, and the lock is removed.
In the following example code, the operation simulates the purchase of a fund from an account.
Note To keep the code simple, the account balance is read from local data as if it was free from race conditions. In a real situation, the data would be read from the cache and would require a lock.
public boolean executeOperation() throws Exception {
String fundCode = this.getValueAt("fund.code").toString();
BigDecimal amount = new BigDecimal((long)this.getValueAt("amount"));
// for simplicity of the example, assume the balance is free of race condition,
// in a real case, another lock is needed
BigDecimal balance = (BigDecimal)this.getValueAt("account.balance");
String lock = "lock-" + fundCode;
RCache rc = RCache.getInstance();
boolean isLocked = false;
try{
// to reduce the race condition time, the less the better for this race section
// try to lock fund.id
isLocked = rc.tryToLock(lock, 30000, 30);
// "Can't acquire the lock, the operation failed!"
if (!isLocked)
{
this.setValueAt("tstatus", STATUS_RACE);
return false; // will not update the account
}
if (amount.compareTo(balance) > 0)
{
this.setValueAt("tstatus", STATUS_BALANCE);
return false;
}
BigDecimal quota = new BigDecimal((Long)rc.pullData(this.getElementAt("fund.quota"), fcode));
if(amount.compareTo(quota) > 0)
{
this.setValueAt("tstatus", STATUS_QUOTA);
return false;
}
// update balance locally
balance = balance.subtract(amount);
this.setValueAt("account.balance", balance);
// update quota
this.setValueAt("fund.quota", quota.subtract(amount).longValue());
rc.pushData(this.getElementAt("fund.quota"), fcode);
}finally{
if(isLocked) rc.unlock(lock);
}
this.setValueAt("tstatus", STATUS_SUCCESS);
return true; // will update the fund
}
See also:
Go up to
How to use the remote cache