Mark: http://jimgreat.iteye.com/blog/1596058
One method
For spring-data-redis, should use "redisTemplate.execute(new SessionCallback<Object>{..}); " for synchronous redis transaction(watch, multi, exec).
// make sure atomic operation for taskKey in Redis
// if retry count is larger than 5 times, abandon it.
redisTemplate.execute(new SessionCallback<Integer>() {
@Override
public Integer execute(RedisOperations operations) throws DataAccessException {
int retries = 5;
do {
// redis watch
operations.watch(taskKey);
Vo vo = handle.getTaskData(taskKey, Vo.class);
boolean needUpdate = checkForUpdate(vo, taskKey, event);
if (!needUpdate) {
log.warn("Save: [{}] is abandoned for taskKey: {}, since checkForUpdate false.",
notification, taskKey);
break;
}
// begin transaction
operations.multi();
if (event.isComplete()) {
vo.setStatus(Status.READY);
vo.complete();
}
vo.setSequenceNumber(sequenceNumber);
handle.updateTaskData(taskKey, vo);
// commit transaction
List<Object> result = operations.exec();
if (result != null) {
log.info("Save: [{}] is saved to taskKey: {}.", notification, taskKey);
break;
}
else if (retries == 1) {
log.warn("Save: [{}] is abandoned for taskKey: {}, since over retries: {}.", notification,
taskKey, retries);
}
retries--;
log.info("Save taskKey: {}, retry: {}.", taskKey, retries);
} while (retries > 0);
return retries;
}
});
The other method
Use lua RedisScript (org.springframework.data.redis.core.script.DefaultRedisScript), lua .
example: http://www.cnblogs.com/yanghuahui/p/3697996.html