diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicLong.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicLong.java index c3d5083b4..c0794b7cd 100644 --- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicLong.java +++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/support/atomic/RedisAtomicLong.java @@ -17,9 +17,13 @@ package org.springframework.data.keyvalue.redis.support.atomic; import java.io.Serializable; import java.util.Collections; +import java.util.concurrent.Callable; +import org.springframework.data.keyvalue.redis.connection.RedisConnectionFactory; import org.springframework.data.keyvalue.redis.core.KeyBound; import org.springframework.data.keyvalue.redis.core.RedisOperations; +import org.springframework.data.keyvalue.redis.core.RedisTemplate; +import org.springframework.data.keyvalue.redis.core.SessionCallback; import org.springframework.data.keyvalue.redis.core.ValueOperations; /** @@ -35,6 +39,41 @@ public class RedisAtomicLong extends Number implements Serializable, KeyBound operations; private RedisOperations generalOps; + + /** + * Constructs a new RedisAtomicLong instance. + * + * @param redisCounter redis counter + * @param factory connection factory + */ + public RedisAtomicLong(String redisCounter, RedisConnectionFactory factory) { + RedisTemplate redisTemplate = new RedisTemplate(factory); + redisTemplate.setExposeConnection(true); + this.key = redisCounter; + this.generalOps = redisTemplate; + this.operations = generalOps.opsForValue(); + if (this.operations.get(redisCounter) == null) { + set(0); + } + } + + /** + * Constructs a new RedisAtomicLong instance. + * + * @param redisCounter + * @param factory + * @param initialValue + */ + public RedisAtomicLong(String redisCounter, RedisConnectionFactory factory, long initialValue) { + RedisTemplate redisTemplate = new RedisTemplate(factory); + redisTemplate.setExposeConnection(true); + this.key = redisCounter; + this.generalOps = redisTemplate; + this.operations = generalOps.opsForValue(); + this.operations.set(redisCounter, initialValue); + } + + /** * Constructs a new RedisAtomicLong instance. Uses as initial value * the data from the backing store (sets the counter to 0 if no value is found). @@ -109,20 +148,26 @@ public class RedisAtomicLong extends Number implements Serializable, KeyBound() { + + @Override + public Boolean execute(RedisOperations operations) { + for (;;) { + operations.watch(Collections.singleton(key)); + if (expect == get()) { + generalOps.multi(); + set(update); + if (operations.exec() != null) { + return true; + } + } + { + return false; + } } } - else { - return false; - } - } + }); } /** @@ -131,15 +176,15 @@ public class RedisAtomicLong extends Number implements Serializable, KeyBound() { + @Override + public Long call() throws Exception { + long value = get(); + generalOps.multi(); + operations.increment(key, 1); return value; } - } + }); } /** @@ -148,15 +193,15 @@ public class RedisAtomicLong extends Number implements Serializable, KeyBound() { + @Override + public Long call() throws Exception { + long value = get(); + generalOps.multi(); + operations.increment(key, -11); return value; } - } + }); } /** @@ -165,16 +210,16 @@ public class RedisAtomicLong extends Number implements Serializable, KeyBound() { + @Override + public Long call() throws Exception { + long value = get(); + generalOps.multi(); + set(value + delta); return value; } - } + }); } /** @@ -202,8 +247,7 @@ public class RedisAtomicLong extends Number implements Serializable, KeyBound