最近在研究redis事务一致性的问题,有一点心得,随笔记录下与大家分享.
Redis的事务和传统关系数据库的事务并不相同.在关系型数据库中,开始事务用到BEGIN,然后执行相应的操作,最后用户可以选择发送commit来确认之前的操作,也可以发送rollback来放弃之前的修改操作!
当然在Redis中也有简单的事务命令.即使用Multi为开始,之后跟着的命令会被串联,最后以EXEC结束. 但是这种方法有一种问题,就是在EXEC在调用之前不会执行任务实际操作,也就是说我们没有办法读取数据判断执行相应的业务逻辑.
当然在某种情况下这种方法也会有助于提高redis的性能.原因是redis在执行事务的过程中,会延迟执行之前的命令直到客户端发送EXEC命令为止.这种一次性发送多个命令,然后等待所有回复出现的做法通常我们称作为流水线.它可以
有效的减少redis服务器与客户端之间的网络通信次数来提升redis在执行多个命令时的性能.
watch命令: 用户使用watch命令对某一个键监视,直到用户执行EXEC命令的这段时间里,如果有其他的客户端抢先对任何被监视的键进行了替换,更新或者删除操作,那么该用户在执行EXEC命令的时候,事务将失败并返回一个错误.
通过使用此命令,我们可以确保使用到的数据不会被其他用户改动来避免出错
unwathc命令: 此命令在watch命令之后执行,在Multi命令之前执行,用来对连接进行重置.
通过watch命令其实我们可以判定出redis是使用了乐观锁.那么为什么redis没有实现典型的加锁功能呢? 我想还是为了保证数据读取操作的高速性吧.在传统的关系型数据库中,在执行增删改操作的时候,数据库会对被访问的数据行进行加锁,
知道事务的提交(commit)或者回滚(rollback)如果有其他的客户端试图对被加锁的行数据进行更改,那么该客户端将会被阻塞,直到上一个事务执行完毕.加锁在实际使用中非常有效,但是有个很大的缺点就是上一个事务执行的时间越长,那么等待
解锁的客户端被阻塞的时间就会越长.所以redis为了减少客户端阻塞的时间,并没有在watch命令监视的键上加锁.只是在数据抢先被修改的情况下通知watch命令的客户端.这种做法我们称之为乐观锁.反之,一般的关系型数据库的加锁操作称之为悲观锁.
redis使用乐观锁极大的增加了它的查询性能,因为客户端永远不必花时间去等待上一个锁的释放.他们只需要在自己执行事务失败的时候进行重试即可.