home

You can't rollback Redis transactions

Feb 05, 2013

When you think transaction, you probably think of being able to rollback changes if something goes wrong. For example, none of the inserts below will be committed, since the 3rd one violates a not-null constraint:

pg.transaction do |conn|
  conn.exec("insert into users values (1, 'john')")
  conn.exec("insert into users values (2, 'bill')")
  conn.exec("insert into users values (3, null)") #exception causes implicit rollback
end
# no rows were inserted

This isn't the case in Redis (with either multi/exec/discard or scripting):

redis.multi do
  redis.set 'user:1', 'john'
  redis.set 'user:2', 'bill'
  redis.llen 'user:1' # exception, no rollback possible
end
# user:1 and user:2 will be set

What transactions and scripting in Redis do is two things. First, it guarantees sequential and uninterrupted commands. Second, it guarantees that all or none of your commands are run - assuming you don't have a bug in your code. The only way, that I know of, for a command to fail in Redis is that you either run out of memory, use the wrong syntax or use a command against the wrong type of key (such as I did in this example).

If you want to rollback, you'll have to do it yourself.