private RedisAtomicLong(String redisCounter, RedisConnectionFactory factory, Long initialValue) {
    RedisTemplate<String, Long> redisTemplate = new RedisTemplate<String, Long>();
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.setValueSerializer(new GenericToStringSerializer<Long>(Long.class));
    redisTemplate.setExposeConnection(true);
    redisTemplate.setConnectionFactory(factory);
    redisTemplate.afterPropertiesSet();

    this.key = redisCounter;
    this.generalOps = redisTemplate;
    this.operations = generalOps.opsForValue();

    if (initialValue == null) {
      if (this.operations.get(redisCounter) == null) {
        set(0);
      }
    } else {
      set(initialValue);
    }
  }
  /**
   * Atomically sets the value to the given updated value if the current value {@code ==} the
   * expected value.
   *
   * @param expect the expected value
   * @param update the new value
   * @return true if successful. False return indicates that the actual value was not equal to the
   *     expected value.
   */
  public boolean compareAndSet(final long expect, final long update) {
    return generalOps.execute(
        new SessionCallback<Boolean>() {

          @SuppressWarnings("unchecked")
          @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;
              }
            }
          }
        });
  }
 @Override
 public void rename(String newKey) {
   generalOps.rename(key, newKey);
   key = newKey;
 }
 @Override
 public Boolean persist() {
   return generalOps.persist(key);
 }
 @Override
 public Long getExpire() {
   return generalOps.getExpire(key);
 }
 @Override
 public Boolean expireAt(Date date) {
   return generalOps.expireAt(key, date);
 }
 @Override
 public Boolean expire(long timeout, TimeUnit unit) {
   return generalOps.expire(key, timeout, unit);
 }
 /**
  * Constructs a new <code>DefaultRedisMap</code> instance.
  *
  * @param key
  * @param operations
  */
 public DefaultRedisMap(String key, RedisOperations<String, ?> operations) {
   this.hashOps = operations.boundHashOps(key);
 }