title: How to implement transaction in Spring Data Redis in a clean way?
body: <p>I am following RetwisJ tutorial available <a href="http://docs.spring.io/spring-data/data-keyvalue/examples/retwisj/current/" rel="noreferrer">here</a>. In this I don't think Redis transactions are implemented. For example, in the following function, if some exception occurs in between, the data will be left in an inconsistent state.
  I want to know how a function like the following can be implemented in <strong>Spring Data Redis</strong> as a single transaction:  </p>
  
  <pre><code>public String addUser(String name, String password) {
          String uid = String.valueOf(userIdCounter.incrementAndGet());
  
          // save user as hash
          // uid -&gt; user
          BoundHashOperations&lt;String, String, String&gt; userOps = template.boundHashOps(KeyUtils.uid(uid));
          userOps.put("name", name);
          userOps.put("pass", password);
          valueOps.set(KeyUtils.user(name), uid);
  
          users.addFirst(name);
          return addAuth(name);
      }
  </code></pre>
  
  <p>Here <code>userIdCounter</code>, <code>valueOps</code> and <code>users</code> are initialized in the constructor. I have come across <a href="http://docs.spring.io/spring-data/redis/docs/current/reference/html/redis.html" rel="noreferrer">this</a> in the documentation(section 4.8), but I can't figure out how to fit that into this function where some variables are initialized outside the function(please don't tell I have to initialize these variables in each and every function where I need transactions!).  </p>
  
  <p><strong>PS:</strong> Also is there any <code>@Transaction</code> annotation or transaction manager available for Spring Data Redis?</p>
  
  <p><strong>UPDATE:</strong> I have tried using <code>MULTI</code>, <code>EXEC</code>. The code which I have written is for another project, but when its applied to this problem it'll be as follows:</p>
  
  <pre><code>public String addMyUser(String name, String password) {
          String uid = String.valueOf(userIdCounter.incrementAndGet());
          template.execute(new SessionCallback&lt;Object&gt;() {
              @Override
              public &lt;K, V&gt; Object execute(RedisOperations&lt;K, V&gt; operations)
                      throws DataAccessException {
                  operations.multi();
                  getUserOps(operations, KeyUtils.uid(uid)).put("name", name);
                  getUserOps(operations, KeyUtils.uid(uid)).put("pass", password);
                  getValueOps(operations).set(KeyUtils.user(name), uid);
                  getUserList(operations, KeyUtils.users()).leftPush(name);
                  operations.exec();
                  return null;
              }
          });
          return addAuth(name);
      }
      private ValueOperations&lt;String, String&gt; getValueOps(RedisOperations operations) {
          return operations.opsForValue();
      }
      private BoundHashOperations&lt;String, String, String&gt; getUserOps(RedisOperations operations, String key) {
          return operations.boundHashOps(key);
      }
      private BoundListOperations&lt;String, String&gt; getUserList(RedisOperations operations, String key) {
          return operations.boundListOps(key);
      }
  </code></pre>
  
  <p>Please tell whether this way of using <code>MULTI</code>, <code>EXEC</code> is recommended or not.</p>