Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Eek. Locking the entire data set to perform transactions? Isn't that so... MyISAM? Does rolling the transaction back work? The optimistic lock is not a great solution either: instead of deadlocking while waiting for a lock to be released, you are now stuck in a while (!saved) loop. Imagine two web pages trying to update the same resource at the same time.

Also this part of the config:

  save 900 1
  save 300 10
  save 60 10000
is not at all obvious. Maybe it's better documented in the sample config.


According to the first comment, the part about locking the whole data set for MULTI is not accurate. Only the connection calling that is stalled, which makes perfect sense.


Ah: http://redis.io/commands/multi. So the problem with this approach is that there are no consistent reads. If I say:

  MULTI
  get foo # Returns 'abc'
  set foo 'abcd' # (as in application code said foo += 'd')
  EXEC
while another process sets foo to 'xyz' between my get and set, I just overwrote that value. No serializable transactions.


MULTI/EXEC is completely atomic and transactional.

You can perform just writes inside the block. If you want atomicity with reads in the middle, you need to use WATCH/MULTI/EXEC that uses an optimistic locking algorithm.


Ah, that makes sense. I imagine allowing atomic reads without WATCH would complicate the code quite a bit.


Indeed, not very Redis-ish :)

With WATCH is very easy. WATCH this keys. Perform your reads. Prepare to write in a transaction. If at least one key was modified in the meantime the transaction will fail.


im not exactly sure about that but i know that at least for integers there are atomic update commands and that for strings there are atomic append commands.

so for this you would really just want to do: APPEND foo d

or for more complex situations you could do use WATCH instead of MULTI so that you can get the intermediate results. so for your example:

WATCH foo GET foo ->value //calculate new_value MULTI SET foo new_value EXEC

now if at any other operation (not part of this connection) modifies foo then the transaction will be aborted.

GET foo -> value //application logic to update value GETSET foo new_value ->prev

then prev will contain the value of foo at the time it was set, so you can then use application logic to roll back or redo the transaction


Redis is single-thread one-process program. Since the execution only happens when EXEC command received, such scenario cannot exist.


It's called optimistic for a reason. You assume there is low contention and configure your client to have random back off.


The configuration options you have quoted are made extremely obvious in the sample configuration and are explained very well. See:

  # Save the DB on disk:
  #
  #   save <seconds> <changes>
  #
  #   Will save the DB if both the given number of seconds and the given
  #   number of write operations against the DB occurred.
  #
  #   In the example below the behaviour will be to save:
  #   after 900 sec (15 min) if at least 1 key changed
  #   after 300 sec (5 min) if at least 10 keys changed
  #   after 60 sec if at least 10000 keys changed


My point is the OP talks about how all the options are self-evident.


Maybe not, but I found the docs in about 10 seconds.

http://redis.io/topics/persistence


Warning, the documentation was not updated with the current behavior!

Now I clearly state in the doc that transactions are reflected also in the append only file, so there is no chance of partial reply.

Transactions are also applied to the master -> slave link, so also slaves will either have the full transaction or nothing.

Thanks to @garybernhardt on twitter for noticing this problem.


MyISAM doesn't support transactions.


My point exactly. MyISAM supports locking the entire table, performing the actions you want to perform and releasing the lock. And there is no rollback, if something goes wrong. The only thing this guarantees is that you have exclusive access to the data. Seems to me that this is what MULTI does as well.

EDIT: looks like there is rollback support: http://redis.io/commands/discard




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: