redis中的事务跟关系型数据库中的事务是一个相似的概念,但是有不同之处。关系型数据库事务执行失败后面的sql语句不在执行,而redis中的一条命令执行失败,其余的命令照常执行。
redis中开启一个事务是使用multi,相当于beginstart transaction,exec提交事务,discard取消队列命令(非回滚操作)。
|
MySQL
|
Redis
|
开启
|
start transaction/begin
|
multi
|
语句
|
普通SQL
|
普通命令
|
失败
|
rollback 回滚
|
discard 取消
|
成功
|
commit
|
exec
|
事务命令
• DISCARD
取消事务,放弃执行事务块内的所有命令。
• EXEC
执行所有事务块内的命令。
• MULTI
标记一个事务块的开始。
• UNWATCH
取消 WATCH 命令对所有 key 的监视。
• WATCH key [key ...]
监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
Redis事务中的锁机制
举例:我正在买票
Ticket -1 , money -100
而票只有1张, 如果在我multi之后,和exec之前, 票被别人买了,即ticket变成0了.
我该如何观察这种情景,并不再提交
悲观的想法:
世界充满危险,肯定有人和我抢, 给ticket上锁, 只有我能操作. [悲观锁]
乐观的想法:
没有那么人和我抢,因此,我只需要注意,有没有人更改ticket的值就可以了 [乐观锁]
举例:redis基于watch实现乐观锁,只要发现监视的对象的值发生变化就取消操作。
用户A买票,购买完票在队列,没有提交
127.0.0.1:6379> set 12306 1 OK 127.0.0.1:6379> WATCH 12306 OK 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> set 12306 0 QUEUED
用户B买票直接提交了
127.0.0.1:6379> get 12306 "1" 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> set 12306 0 QUEUED 127.0.0.1:6379> EXEC 1) OK 127.0.0.1:6379>
当用户A经过一番思考后决定要买票时发现票已经被买走了。
127.0.0.1:6379> set 12306 1 OK 127.0.0.1:6379> WATCH 12306 OK 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> set 12306 0 QUEUED 127.0.0.1:6379> EXEC (nil)
如果A用户不加watch,导致两个用户都可以购买成功。但是只有一张票
服务管理命令
- Info 查看redis当前状态的所有参数,如果想查看某一个项:info clients、INFO Memory、info Persistence等
- Clinet list
- Client kill ip:port
- config get *
- CONFIG GET/SET 动态修改
- Dbsize 查看当前数据库key的大小 (用info keyspace也可以来查看redis key的详情)
- FLUSHALL 清空所有数据(包括持久化的数据)⚠️ 危险
- select 0 (默认总共有15个库,编号从0-15。对于集群环境所有的节点必须保持在0号库)
- FLUSHDB 清空当前库
- MONITOR 监控实时指令
- SHUTDOWN 关闭服务器
- save 将当前数据保存
- SLAVEOF host port 主从配置
- SLAVEOF NO ONE
- SYNC 主从同步
- ROLE返回主从角色
善于用help查看帮助
127.0.0.1:6379> CLIENT help 1) CLIENT <subcommand> arg arg ... arg. Subcommands are: 2) id -- Return the ID of the current connection. 3) getname -- Return the name of the current connection. 4) kill <ip:port> -- Kill connection made from <ip:port>. 5) kill <option> <value> [option value ...] -- Kill connections. Options are: 6) addr <ip:port> -- Kill connection made from <ip:port> 7) type (normal|master|replica|pubsub) -- Kill connections by type. 8) skipme (yes|no) -- Skip killing current connection (default: yes). 9) list [options ...] -- Return information about client connections. Options: 10) type (normal|master|replica|pubsub) -- Return clients of specified type. 11) pause <timeout> -- Suspend all Redis clients for <timout> milliseconds. 12) reply (on|off|skip) -- Control the replies sent to the current connection. 13) setname <name> -- Assign the name <name> to the current connection. 14) unblock <clientid> [TIMEOUT|ERROR] -- Unblock the specified blocked client.
常用全局key操作
KEYS * 查看KEY支持通配符
DEL 删除给定的一个或多个key
EXISTS 检查是否存在(可以在代码中操作,没有就去mysql中取)
TYPE 返回键所存储值的类型
EXPIRE PEXPIRE 以秒毫秒设定生存时间
TTL PTTL 以秒毫秒为单位返回生存时间
PERSIST 取消生存实现设置